Import ABACUS++G_8 code; cleanup files; new README
This commit is contained in:
@@ -0,0 +1,307 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/BETHE/Base.cc
|
||||
|
||||
Purpose: defines functions in Base class,
|
||||
providing a unified base object for all
|
||||
Bethe Ansatz integrable models.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// 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];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// DEPRECATED
|
||||
Base::Base (const Heis_Chain& RefChain, int M)
|
||||
: Charge(M), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings))
|
||||
{
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) Nrap[i] = 0;
|
||||
Nrap[0] = M;
|
||||
|
||||
Nraptot = 0;
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
|
||||
|
||||
// The id of this is zero by definition
|
||||
id = 0LL;
|
||||
|
||||
// Now compute the Ix2_infty numbers
|
||||
|
||||
(*this).Compute_Ix2_limits(RefChain);
|
||||
|
||||
}
|
||||
*/
|
||||
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()) cout << "error: Nstrings = " << RefChain.Nstrings << "\tNrap.size = " << Nrapidities.size() << endl;
|
||||
|
||||
if (RefChain.Nstrings != Nrapidities.size()) JSCerror("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;
|
||||
|
||||
//id = id_ref;
|
||||
|
||||
//cout << "In Base constructor: id_ref = " << id_ref << " and Nrapidities = " << Nrap << endl;
|
||||
|
||||
// Check consistency of Nrapidities vector with RefChain
|
||||
|
||||
//if (RefChain.Nstrings != Nrap.size()) JSCerror("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];
|
||||
|
||||
// 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 < JSC::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 * JSC::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 * JSC::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;
|
||||
}
|
||||
|
||||
// Fudge, for strings:
|
||||
//if (RefChain.Str_L[j] >= 1) Ix2_max[j] += 2;
|
||||
//Ix2_max[j] += 2;
|
||||
}
|
||||
|
||||
} // if XXZ_gpd
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,29 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
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 JSC
|
||||
@@ -0,0 +1,277 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c) 2006-9.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/BETHE/Offsets.cc
|
||||
|
||||
Purpose: defines functions in Offsets class.
|
||||
|
||||
|
||||
Last modified: 19/10/2009
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// 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) JSCerror("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) JSCerror("Wrong nparticles.size in Offsets constructor.");
|
||||
|
||||
//if (base.Nrap[0] != (nparticles[3] + nparticles[2] + base.Mdown - nparticles[0] - nparticles[1])) JSCerror("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;
|
||||
JSCerror("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;
|
||||
JSCerror("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) JSCerror("nparticles[0] too large in Offsets constructor.");
|
||||
if (nparticles[1] > base.Nrap[0]/2) JSCerror("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) JSCerror("nparticles[2] too large in Offsets constructor.");
|
||||
if (nparticles[3] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) JSCerror("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;
|
||||
JSCerror("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 < JSC::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 = JSC::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 < JSC::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 = JSC::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;
|
||||
JSCerror("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)) JSCerror("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 JSC
|
||||
@@ -0,0 +1,89 @@
|
||||
/****************************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c) 2006.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
Combinatorics.cc
|
||||
|
||||
Defines all class related to combinatorics.
|
||||
|
||||
LAST MODIFIED: 04/09/06
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
Choose_Table::Choose_Table ()
|
||||
: Npower(0ULL), Npowerp1(1ULL), table(new unsigned long long int[1])
|
||||
{
|
||||
table[0] = 1ULL;
|
||||
}
|
||||
|
||||
Choose_Table::Choose_Table (int Npower_ref)
|
||||
: Npower(Npower_ref), Npowerp1(Npower_ref + 1ULL)
|
||||
{
|
||||
dim = Npowerp1 * Npowerp1;
|
||||
|
||||
// We can only go up to ULL_MAX:
|
||||
if (log(DP(ULONG_LONG_MAX)) < DP(Npowerp1) * log(2.0))
|
||||
JSCerror("Choose_Table: too large to contruct.");
|
||||
|
||||
table = new unsigned long long int[dim];
|
||||
|
||||
(*this).Fill_table();
|
||||
}
|
||||
|
||||
void Choose_Table::Fill_table()
|
||||
{
|
||||
table[0] = 1ULL;
|
||||
int n,m;
|
||||
for (n = 0; n <= Npower; ++n) {
|
||||
table[Npowerp1 * n] = 1ULL;
|
||||
for (m = 1; m < n; ++m) {
|
||||
table[Npowerp1 * n + m] = table[Npowerp1 * (n-1) + m - 1] + table[Npowerp1 * (n-1) + m];
|
||||
}
|
||||
table[Npowerp1 * n + n] = 1ULL;
|
||||
for (m = n+1; m <= Npower; ++m)
|
||||
table[Npowerp1 * n + m] = 0ULL;
|
||||
}
|
||||
}
|
||||
|
||||
int Choose_Table::power()
|
||||
{
|
||||
return(Npower);
|
||||
}
|
||||
|
||||
unsigned long long int Choose_Table::choose(int N, int M)
|
||||
{
|
||||
if (N < 0 || N > Npower) JSCerror("N out of bounds in choose(N,M).");
|
||||
if (M < 0 || M > Npower) JSCerror("M out of bounds in choose(N,M).");
|
||||
|
||||
return(table[Npowerp1 * N + M]);
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& s, Choose_Table& Ref_table)
|
||||
{
|
||||
s << endl;
|
||||
for (int n = 0; n <= Ref_table.power(); ++n) {
|
||||
for (int m = 0; m <= Ref_table.power(); ++m)
|
||||
s << Ref_table.choose(n, m) << " ";
|
||||
s << endl;
|
||||
}
|
||||
s << endl;
|
||||
return(s);
|
||||
}
|
||||
|
||||
Choose_Table::~Choose_Table()
|
||||
{
|
||||
delete[] table;
|
||||
}
|
||||
|
||||
|
||||
} // namespace JSC
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: 2CBG_ThLim.cc
|
||||
|
||||
Purpose: solves the TBA equations for the 2-component Bose gas
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 7) JSCerror("Wrong number of arguments to 2CBG_ThLim executable. Use c(best to set to 1), mu, Omega, kBT, TT(minutes), bool Save_data (0 == false).");
|
||||
|
||||
DP c_int = atof(argv[1]);
|
||||
DP mu = atof(argv[2]);
|
||||
DP Omega = atof(argv[3]);
|
||||
DP kBT = atof(argv[4]);
|
||||
int Max_Secs = 60 * atoi(argv[5]);
|
||||
bool Save_data = bool(atoi(argv[6]));
|
||||
|
||||
if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
|
||||
if (Omega <= 0.0) JSCerror("Give a strictly positive Omega, otherwise the algorithm cannot converge.");
|
||||
if (kBT <= 0.0) JSCerror("Negative T ? You must be a string theorist.");
|
||||
if (Max_Secs < 10) JSCerror("Give more time.");
|
||||
|
||||
//cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
|
||||
|
||||
Solve_2CBG_TBAE_via_refinements (c_int, mu, Omega, kBT, Max_Secs, Save_data);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Analyze_RAW_File.cc
|
||||
|
||||
Purpose: give some statistics for the matrix element distribution in a raw file.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 4) {
|
||||
cout << "Argument needed: rawfile, iKmin, iKmax." << endl;
|
||||
JSCerror("");
|
||||
}
|
||||
|
||||
const char* rawfilename = argv[1];
|
||||
int iKmin = atoi(argv[2]);
|
||||
int iKmax = atoi(argv[3]);
|
||||
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(rawfilename);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << rawfilename << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
DP sumFFsq = 0.0;
|
||||
DP sumFF4 = 0.0;
|
||||
DP sumFFsqlnFFsq = 0.0;
|
||||
|
||||
Vect<int> nFFatK (0, iKmax - iKmin + 1);
|
||||
Vect<DP> sumFFsqatK (0.0, iKmax - iKmin + 1);
|
||||
Vect<DP> sumFF4atK (0.0, iKmax - iKmin + 1);
|
||||
Vect<DP> sumFFsqlnFFsqatK (0.0, iKmax - iKmin + 1);
|
||||
|
||||
int nread = 0;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
|
||||
nread++;
|
||||
sumFFsq += FF*FF;
|
||||
sumFF4 += FF*FF*FF*FF;
|
||||
sumFFsqlnFFsq += FF*FF * log(FF*FF);
|
||||
|
||||
if (iK >= iKmin && iK <= iKmax) {
|
||||
nFFatK[iK-iKmin] += 1;
|
||||
sumFFsqatK[iK - iKmin] += FF*FF;
|
||||
sumFF4atK[iK - iKmin] += FF*FF*FF*FF;
|
||||
sumFFsqlnFFsqatK[iK - iKmin] += FF*FF * log(FF*FF);
|
||||
}
|
||||
}
|
||||
|
||||
RAW_infile.close();
|
||||
|
||||
cout << "Inverse participation ratio: \t" << sumFF4/(sumFFsq*sumFFsq) << endl;
|
||||
// Entropy is -sum (FFsq/sumFFsq) * ln(FFsq/sumFFsq) = sum (FFsq lnFFsq - FFsq ln sumFFsq)/sumFFsq
|
||||
cout << "Entropy: \t" << -(sumFFsqlnFFsq - sumFFsq * log(sumFFsq))/sumFFsq << endl;
|
||||
|
||||
cout << "iK\tnFFatK\tIPRatiK\tentropyatiK:" << endl;
|
||||
for (int iK = iKmin; iK <= iKmax; ++iK) cout << iK << "\t" << nFFatK[iK-iKmin] << "\t" << sumFF4atK[iK-iKmin]/(sumFFsqatK[iK - iKmin] * sumFFsqatK[iK - iKmin]) << "\t" << -(sumFFsqlnFFsqatK[iK-iKmin] - sumFFsqatK[iK-iKmin] * log(sumFFsqatK[iK-iKmin]))/sumFFsqatK[iK-iKmin]<< endl;
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Check_RAW_File.cc
|
||||
|
||||
Purpose: from a .raw_srt file, check that nonzero momentum states
|
||||
appear (only) twice, and zero momentum ones (only) once.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 7) { // print out some instructions
|
||||
cout << "Usage of Check_RAW_File executable: provide the following arguments:" << endl;
|
||||
cout << "(sorted!) raw file name, iKmin, iKmax, sympoint, FFmin, check_option." << endl;
|
||||
cout << "Check option: 0 == check for missing states, 1 == check for multiply-appearing states." << endl;
|
||||
}
|
||||
|
||||
char* rawfilename = argv[1];
|
||||
int iKmin = atoi(argv[2]);
|
||||
int iKmax = atoi(argv[3]);
|
||||
int sympoint = atoi(argv[4]);
|
||||
DP FFmin = atof(argv[5]);
|
||||
int check_option = atoi(argv[6]);
|
||||
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(rawfilename);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << rawfilename << endl;
|
||||
JSCerror("Could not open sorted RAW_infile... ");
|
||||
}
|
||||
|
||||
DP omega_next, omega, omega_prev;
|
||||
int iK_next, iK, iK_prev;
|
||||
DP FF_next, FF, FF_prev;
|
||||
//int conv_next, conv, conv_prev;
|
||||
DP dev_next, dev, dev_prev;
|
||||
string label_next, label, label_prev;
|
||||
|
||||
if (check_option > 1) {
|
||||
FF = 0.0;
|
||||
FF_prev = 0.0;
|
||||
FF_next = 0.0;
|
||||
FFmin = -1.0;
|
||||
}
|
||||
|
||||
//RAW_infile >> omega >> iK >> FF >> conv >> label;
|
||||
RAW_infile >> omega >> iK;
|
||||
if (check_option <= 1) RAW_infile >> FF;
|
||||
RAW_infile >> dev;
|
||||
RAW_infile >> label;
|
||||
//RAW_infile >> omega_next >> iK_next >> FF_next >> conv_next >> label_next;
|
||||
RAW_infile >> omega_next >> iK_next;
|
||||
if (check_option <= 1) RAW_infile >> FF_next;
|
||||
RAW_infile >> dev_next;
|
||||
RAW_infile >> label_next;
|
||||
|
||||
int line = 1;
|
||||
|
||||
char a;
|
||||
|
||||
|
||||
while (fabs(FF) > FFmin && RAW_infile.peek() != EOF) {
|
||||
|
||||
//omega_prev = omega; iK_prev = iK; FF_prev = FF; conv_prev = conv; label_prev = label;
|
||||
omega_prev = omega; iK_prev = iK; FF_prev = FF; dev_prev = dev; label_prev = label;
|
||||
//omega = omega_next; iK = iK_next; FF = FF_next; conv = conv_next; label = label_next;
|
||||
omega = omega_next; iK = iK_next; FF = FF_next; dev = dev_next; label = label_next;
|
||||
//RAW_infile >> omega_next >> iK_next >> FF_next >> conv_next >> label_next;
|
||||
RAW_infile >> omega_next >> iK_next;
|
||||
if (check_option <= 1) RAW_infile >> FF_next; // for non-Z checks
|
||||
RAW_infile >> dev_next;
|
||||
RAW_infile >> label_next;
|
||||
//cout << "checking line " << line << endl;
|
||||
//cout << omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << label_prev << endl
|
||||
// << omega << "\t" << iK << "\t" << FF << "\t" << label << endl
|
||||
// << omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << label_next << endl;
|
||||
line++;
|
||||
|
||||
if (label.compare(label_next) == 0)
|
||||
cout << "Identical labels around line " << line << ": " << endl
|
||||
<< omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl;
|
||||
|
||||
if (check_option == 0 && iK != 0 && iK != sympoint && iK >= iKmin && iK <= iKmax
|
||||
&& fabs((FF - FF_prev)/(FF + FF_prev)) > 1.0e-6 && fabs((FF - FF_next)/(FF + FF_next)) > 1.0e-6) {
|
||||
|
||||
cout << "State missing around line " << line << ": " << endl
|
||||
//<< omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << conv_prev << "\t" << label_prev << endl
|
||||
<< omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << dev_prev << "\t" << label_prev << endl
|
||||
//<< omega << "\t" << iK << "\t" << FF << "\t" << conv << "\t" << label << endl
|
||||
<< omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl
|
||||
//<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << conv_next << "\t" << label_next << endl;
|
||||
<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << dev_next << "\t" << label_next << endl;
|
||||
|
||||
cin >> a;
|
||||
//break;
|
||||
}
|
||||
|
||||
if (check_option == 1 && iK_prev == iK && iK == iK_next && fabs((omega - omega_prev)/(omega + omega_prev)) < 1.0e-8 && fabs((omega - omega_next)/(omega + omega_next)) < 1.0e-8 && fabs((FF - FF_prev)/(FF + FF_prev)) < 1.0e-8 && fabs((FF - FF_next)/(FF + FF_next)) < 1.0e-8) {
|
||||
|
||||
cout << "Triple state around line " << line << ": " << endl
|
||||
//<< omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << conv_prev << "\t" << label_prev << endl
|
||||
<< omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << dev_prev << "\t" << label_prev << endl
|
||||
//<< omega << "\t" << iK << "\t" << FF << "\t" << conv << "\t" << label << endl
|
||||
<< omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl
|
||||
//<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << conv_next << "\t" << label_next << endl;
|
||||
<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << dev_next << "\t" << label_next << endl;
|
||||
cin >> a;
|
||||
}
|
||||
|
||||
if (check_option == 2 && iK != 0 && iK != sympoint && iK >= iKmin && iK <= iKmax
|
||||
&& fabs((omega - omega_prev)/(omega + omega_prev)) > 1.0e-6 && fabs((omega - omega_next)/(omega + omega_next)) > 1.0e-6) {
|
||||
|
||||
cout << "State missing around line " << line << ": " << endl
|
||||
<< omega_prev << "\t" << iK_prev << "\t" << dev_prev << "\t" << label_prev << endl
|
||||
<< omega << "\t" << iK << "\t" << dev << "\t" << label << endl
|
||||
<< omega_next << "\t" << iK_next << "\t" << dev_next << "\t" << label_next << endl;
|
||||
|
||||
cin >> a;
|
||||
//break;
|
||||
}
|
||||
|
||||
if (check_option == 3 && iK_prev == iK && iK == iK_next && fabs((omega - omega_prev)/(omega + omega_prev)) < 1.0e-8 && fabs((omega - omega_next)/(omega + omega_next)) < 1.0e-8) {
|
||||
|
||||
cout << "Triple state around line " << line << ": " << endl
|
||||
<< omega_prev << "\t" << iK_prev << "\t" << dev_prev << "\t" << label_prev << endl
|
||||
<< omega << "\t" << iK << "\t" << dev << "\t" << label << endl
|
||||
<< omega_next << "\t" << iK_next << "\t" << dev_next << "\t" << label_next << endl;
|
||||
cin >> a;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF.cc
|
||||
|
||||
Purpose: main function for ABACUS++ for Heisenberg spin-1/2 chain
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 8) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
//cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Heis_DSF z 1.0 100 40 0 100 600 1.0 0" << endl << endl;
|
||||
}
|
||||
|
||||
else if (argc == 8) { // !fixed_iK
|
||||
int ctr = 1;
|
||||
char whichDSF = *argv[ctr++];
|
||||
DP Delta = atof(argv[ctr++]);
|
||||
int N = atoi(argv[ctr++]);
|
||||
int M = atoi(argv[ctr++]);
|
||||
//int iKmin = atoi(argv[5]);
|
||||
//int iKmax = atoi(argv[6]);
|
||||
int Max_Secs = atoi(argv[ctr++]);
|
||||
DP target_sumrule = atof(argv[ctr++]);
|
||||
bool refine = (atoi(argv[ctr++]) == 1);
|
||||
|
||||
// We systematically scan over all momentum integers (to avoid problems with Brillouin folding
|
||||
int iKmin = -1000*N;
|
||||
int iKmax = 1000*N;
|
||||
//Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine, 0, 1);
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// The argument given is the name of the standard args_Heis_DSF arguments file
|
||||
|
||||
/*
|
||||
if (argc == 2) { // Used an input file to provide the arguments
|
||||
|
||||
if (strcmp(argv[1],"help") == 0) { // Output some instructions
|
||||
cout << "Usage of Heis_DSF executable: " << endl;
|
||||
cout << endl << "Provide arguments by either using one of the three following options:" << endl << endl;
|
||||
cout << "1) via an argument file (see the template `args_Heis_DSF' in directory src/EXECS/), for example" << endl << endl;
|
||||
cout << "Heis_DSF args_Heis_DSF" << endl << endl;
|
||||
cout << "2) with arguments (for general momenta scan) whichDSF Delta N M iKmin iKmax Max_Secs refine, for example" << endl << endl;
|
||||
cout << "Heis_DSF z 0.9 100 40 0 50 600 0" << endl << endl;
|
||||
cout << "3) with arguments (for general momenta scan) whichDSF Delta N M iKneeded Max_Secs refine, for example" << endl << endl;
|
||||
cout << "Heis_DSF z 0.9 100 40 20 600 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // read argument file
|
||||
|
||||
ifstream argsfile;
|
||||
argsfile.open(argv[1]);
|
||||
if (argsfile.fail()) {
|
||||
cout << argv[1] << endl;
|
||||
JSCerror("Could not open arguments file.");
|
||||
}
|
||||
|
||||
char junk[256];
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
char whichDSF; argsfile >> whichDSF;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
DP Delta; argsfile >> Delta;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
int N; argsfile >> N;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
int M; argsfile >> M;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
//bool fixed_iK; argsfile >> fixed_iK;
|
||||
//while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
//int iKneeded; argsfile >> iKneeded;
|
||||
int iKmin, iKmax; argsfile >> iKmin >> iKmax;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
int Max_Secs; argsfile >> Max_Secs;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
bool refine; argsfile >> refine;
|
||||
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, refine);
|
||||
}
|
||||
} // if (argc == 2)
|
||||
|
||||
else if (argc == 8) { // fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKneeded = atoi(argv[5]);
|
||||
int Max_Secs = atoi(argv[6]);
|
||||
bool refine = (atoi(argv[7]) == 1);
|
||||
|
||||
//Scan_Heis (whichDSF, Delta, N, M, iKneeded, Max_Secs, refine);
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKneeded, iKneeded, Max_Secs, refine);
|
||||
}
|
||||
|
||||
else if (argc == 9) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
int Max_Secs = atoi(argv[7]);
|
||||
bool refine = (atoi(argv[8]) == 1);
|
||||
|
||||
//Scan_Heis (whichDSF, Delta, N, M, iKneeded, Max_Secs, refine);
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, refine);
|
||||
}
|
||||
|
||||
else JSCerror("Wrong number of arguments to Heis_DSF executable.");
|
||||
*/
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF_GeneralState.cc
|
||||
|
||||
Purpose: main function for ABACUS++ for Heisenberg spin-1/2 chain
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
//cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
}
|
||||
|
||||
else if (argc == 9) { // !fixed_iK
|
||||
int ctr = 1;
|
||||
char whichDSF = *argv[ctr++];
|
||||
DP Delta = atof(argv[ctr++]);
|
||||
int N = atoi(argv[ctr++]);
|
||||
int M = atoi(argv[ctr++]);
|
||||
char* Ix2filenameprefix = argv[ctr++];
|
||||
//int iKmin = atoi(argv[5]);
|
||||
//int iKmax = atoi(argv[6]);
|
||||
int Max_Secs = atoi(argv[ctr++]);
|
||||
DP target_sumrule = atof(argv[ctr++]);
|
||||
bool refine = (atoi(argv[ctr++]) == 1);
|
||||
|
||||
// We systematically scan over all momentum integers (to avoid problems with Brillouin folding
|
||||
int iKmin = -1000*N;
|
||||
int iKmax = 1000*N;
|
||||
|
||||
// Read the Ix2 from the file:
|
||||
// Format is:
|
||||
// base_level, Nrap[base_level], \endl Ix2[base_level], repeat for all occupied base_levels...
|
||||
ifstream Ix2_input_file;
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
filenamestrstream << ".Ix2";
|
||||
string filenamestr = filenamestrstream.str();
|
||||
const char* filename_Cstr = filenamestr.c_str();
|
||||
Ix2_input_file.open(filename_Cstr);
|
||||
if (Ix2_input_file.fail()) {
|
||||
cout << filename_Cstr << endl;
|
||||
JSCerror("Could not open Ix2 input file in Heis_DSF_GeneralState");
|
||||
}
|
||||
|
||||
Heis_Chain chain(1.0, Delta, 0.0, N);
|
||||
|
||||
Vect<int> Nrap_read (0, chain.Nstrings);
|
||||
int level = 0;
|
||||
Vect<Vect<int> > Ix2_read (chain.Nstrings);
|
||||
do {
|
||||
Ix2_input_file >> level;
|
||||
Ix2_input_file >> Nrap_read[level];
|
||||
Ix2_read[level] = Vect<int> (Nrap_read[level]);
|
||||
for (int alpha = 0; alpha < Nrap_read[level]; ++alpha) Ix2_input_file >> Ix2_read[level][alpha];
|
||||
//cout << "Read level = " << level << "\tNrap_read[level] = " << Nrap_read[level] << endl;
|
||||
//cout << "\tIx2_read[level] = " << Ix2_read[level] << endl;
|
||||
} while (Ix2_input_file.peek() != EOF);
|
||||
|
||||
// Construct the Averaging State:
|
||||
Heis_Base base (chain, Nrap_read);
|
||||
|
||||
int paralevel = 0;
|
||||
Vect<int> rank; // dummy
|
||||
Vect<int> nr_processors; // dummy
|
||||
|
||||
if (Delta > 0.0 && Delta < 1.0) {
|
||||
XXZ_Bethe_State AveragingState (chain, base);
|
||||
for (int il = 0; il < chain.Nstrings; ++il) {
|
||||
if (Nrap_read[il] > 0) for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
|
||||
}
|
||||
AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
|
||||
AveragingState.Compute_All(true);
|
||||
|
||||
//cout << "AveragingState read from file: " << AveragingState << endl;
|
||||
// Perform the scan:
|
||||
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
}
|
||||
else if (Delta == 1.0) {
|
||||
XXX_Bethe_State AveragingState (chain, base);
|
||||
for (int il = 0; il < chain.Nstrings; ++il) {
|
||||
for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
|
||||
}
|
||||
AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
|
||||
AveragingState.Compute_All(true);
|
||||
|
||||
// Perform the scan:
|
||||
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
}
|
||||
else if (Delta > 1.0) {
|
||||
XXZ_gpd_Bethe_State AveragingState (chain, base);
|
||||
for (int il = 0; il < chain.Nstrings; ++il) {
|
||||
for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
|
||||
}
|
||||
AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
|
||||
AveragingState.Compute_All(true);
|
||||
|
||||
// Perform the scan:
|
||||
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF_par.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP Delta;
|
||||
int N, M, iKneeded, iKmin, iKmax, Max_Secs;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine;
|
||||
|
||||
if (argc != 8) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF_par executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "mpiexec -np 8 Heis_DSF_par z 1.0 100 40 0 100 600" << endl << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // (argc == 8) correct nr of arguments
|
||||
whichDSF = *argv[1];
|
||||
Delta = atof(argv[2]);
|
||||
N = atoi(argv[3]);
|
||||
M = atoi(argv[4]);
|
||||
iKmin = atoi(argv[5]);
|
||||
iKmax = atoi(argv[6]);
|
||||
Max_Secs = atoi(argv[7]);
|
||||
}
|
||||
|
||||
DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= supercycle_time + 300) JSCerror("Please allow more time in Heis_DSF_par.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
// IMPORTANT PRECONDITION: no flags are being raised in General_Scan in parallel mode, so
|
||||
// the preinitializing serial run must be extensive enough to have flagged all base/type s necessary.
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
while (tnow - tstart < Max_Secs - supercycle_time - 300) { // space for one more supercycle, + 5 minutes safety
|
||||
|
||||
//cout << "rank " << rank << " ready to prepare." << endl;
|
||||
|
||||
if (rank == 0)
|
||||
// Split up thread list into chunks, one per processor
|
||||
Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors);
|
||||
|
||||
//cout << "rank " << rank << " done preparing, ready to scan." << endl;
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax,
|
||||
supercycle_time, target_sumrule, refine, rank, nr_processors);
|
||||
|
||||
//cout << "rank " << rank << " finished scanning, reached wrapup stage." << endl;
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
if (rank == 0)
|
||||
Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors);
|
||||
|
||||
//cout << "rank " << rank << " passed wrapup stage." << endl;
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP Delta;
|
||||
int N, M, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF_par_Prepare executable: " << endl;
|
||||
cout << endl << "This function prepares for ABACUS++G in parallel mode, starting from a preexisting serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
Delta = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
M = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 9 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in Heis_DSF_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
// Split up thread list into chunks, one per processor
|
||||
Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF_par_Run.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP Delta;
|
||||
int N, M, iKmin, iKmax, Max_Secs, supercycle_time, paralevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF_par_Run executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "mpiexec -np 8 Heis_DSF_par_Run z 1 128 64 0 128 [**UPDATE]" << endl << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//else { // (argc == 9) correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
Delta = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
M = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in Heis_DSF_par_Run.");
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
Max_Secs = atoi(argv[n++]);
|
||||
supercycle_time = atoi(argv[n++]);
|
||||
//}
|
||||
|
||||
//DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in Heis_DSF_par_Run.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank_here = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors_here = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
Vect<int> rank (paralevel);
|
||||
Vect<int> nr_processors (paralevel);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank[i] = rank_lower_paralevels[i];
|
||||
nr_processors[i] = nr_processors_lower_paralevels[i];
|
||||
}
|
||||
rank[paralevel-1] = rank_here;
|
||||
nr_processors[paralevel-1] = nr_processors_here;
|
||||
|
||||
if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax,
|
||||
supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare or Wrapup
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP Delta;
|
||||
int N, M, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF_par_Wrapup executable: " << endl;
|
||||
cout << endl << "This function wraps up an ABACUS++G parallel mode run." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
Delta = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
M = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 9 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in Heis_DSF_par_Wrapup.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
// Split up thread list into chunks, one per processor
|
||||
Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Catalogue_Fixed_c_k_Nscaling.cc
|
||||
|
||||
Purpose: Produces sets of data files for correlations, increasing system size at fixed c and momentum.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 7) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Catalogue_Fixed_c_k_Nscaling executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
//cout << "int Nc \t\t number of steps in interaction value" << endl;
|
||||
//cout << "int Nstep \t\t\t Steps to be taken in number of particles: use positive integer values only. Filling will be set to 1 (L == N)" << endl;
|
||||
//cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over (in units of N == Nstep): recommended values: 0 and 2*N" << endl;
|
||||
cout << "int kfact \t\t momentum factor: momemntum will be set to kfact * kF/4" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time" << endl;
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int ia = 1;
|
||||
char whichDSF = *argv[ia++];
|
||||
DP c_int = atof(argv[ia++]);
|
||||
int kfact = atoi(argv[ia++]);
|
||||
DP kBT = atof(argv[ia++]);
|
||||
DP target_sumrule = atof(argv[ia++]);
|
||||
int Max_Secs = atoi(argv[ia++]);
|
||||
|
||||
|
||||
//clock_t StartTime = clock();
|
||||
double StartTime = omp_get_wtime();
|
||||
|
||||
//clock_t ActualTime = StartTime;
|
||||
double ActualTime = omp_get_wtime();
|
||||
|
||||
int Secs_left = Max_Secs;
|
||||
|
||||
int iN = 0;
|
||||
|
||||
int nN = 12;
|
||||
Vect<int> Nv(nN);
|
||||
Nv[0] = 160; Nv[1] = 192; Nv[2] = 224; Nv[3] = 256;
|
||||
Nv[4] = 320; Nv[5] = 384; Nv[6] = 448; Nv[7] = 512;
|
||||
Nv[8] = 640; Nv[9] = 768; Nv[10] = 896; Nv[11] = 1024;
|
||||
|
||||
for (int iN = 0; iN < nN; ++iN) {
|
||||
|
||||
int N = Nv[iN];
|
||||
DP L = N;
|
||||
int iKmin = (kfact * N)/8;
|
||||
int iKmax = iKmin;
|
||||
DP srsat = 0.0;
|
||||
bool refine = false;
|
||||
|
||||
stringstream SRC_stringstream; string SRC_string;
|
||||
Data_File_Name (SRC_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
SRC_stringstream << ".src";
|
||||
SRC_string = SRC_stringstream.str(); const char* SRC_Cstr = SRC_string.c_str();
|
||||
|
||||
fstream srcfile;
|
||||
srcfile.open(SRC_Cstr, fstream::in);
|
||||
if (srcfile.fail()) {
|
||||
srsat = 0.0;
|
||||
refine = false;
|
||||
}
|
||||
else {
|
||||
srcfile >> srsat;
|
||||
refine = true;
|
||||
}
|
||||
srcfile.close();
|
||||
|
||||
ActualTime = omp_get_wtime();
|
||||
Secs_left = int(Max_Secs - (ActualTime - StartTime));
|
||||
|
||||
if (srsat < target_sumrule && Secs_left > Max_Secs/2)
|
||||
// Improve the icmin calculation by one chunk:
|
||||
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Secs_left, target_sumrule, refine);
|
||||
|
||||
ActualTime = omp_get_wtime();
|
||||
|
||||
//Secs_left = int(60*Max_minutes - double(ActualTime - StartTime)/CLOCKS_PER_SEC);
|
||||
Secs_left = int(Max_Secs - (ActualTime - StartTime));
|
||||
cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl;
|
||||
|
||||
if (Secs_left < 60) {
|
||||
cout << "Breaking out after N = " << N << " since time left = " << Secs_left << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
} // while there is time
|
||||
|
||||
} // else if arguments given OK
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF.cc
|
||||
|
||||
Purpose: main function for ABACUS++ for LiebLin gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 11) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF d 1.0 100.0 100 0 200 0.56 600 1.0 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int Max_Secs = atoi(argv[8]);
|
||||
DP target_sumrule = atof(argv[9]);
|
||||
bool refine = (atoi(argv[10]) == 1);
|
||||
|
||||
//cout << "target_sumrule = " << target_sumrule << endl;
|
||||
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine, 0, 1);
|
||||
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_GeneralState.cc
|
||||
|
||||
Purpose: function for ABACUS++ for LiebLin gas, on general states
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 11) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF d 1.0 100.0 100 0 200 0.56 600 1.0 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
int n = 1;
|
||||
char whichDSF = *argv[n++];
|
||||
DP c_int = atof(argv[n++]);
|
||||
DP L = atof(argv[n++]);
|
||||
int N = atoi(argv[n++]);
|
||||
char* Ix2filenameprefix = argv[n++];
|
||||
int iKmin = atoi(argv[n++]);
|
||||
int iKmax = atoi(argv[n++]);
|
||||
//DP kBT = atof(argv[n++]);
|
||||
int Max_Secs = atoi(argv[n++]);
|
||||
DP target_sumrule = atof(argv[n++]);
|
||||
bool refine = (atoi(argv[n++]) == 1);
|
||||
|
||||
// Read the Ix2 from the file:
|
||||
Vect<int> Ix2_input(N);
|
||||
ifstream Ix2_input_file;
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
filenamestrstream << ".Ix2";
|
||||
string filenamestr = filenamestrstream.str();
|
||||
const char* filename_Cstr = filenamestr.c_str();
|
||||
Ix2_input_file.open(filename_Cstr);
|
||||
if (Ix2_input_file.fail()) {
|
||||
cout << filename_Cstr << endl;
|
||||
JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
Ix2_input_file >> Ix2_input[i];
|
||||
//cout << i << "\t" << Ix2_input[i] << endl;
|
||||
}
|
||||
|
||||
// Now define the AveragingState
|
||||
LiebLin_Bethe_State AveragingState(c_int, L, N);
|
||||
AveragingState.Ix2 = Ix2_input;
|
||||
AveragingState.Compute_All(true);
|
||||
|
||||
//cout << "Averaging state: " << AveragingState << endl;
|
||||
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine, 0, 1);
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine);
|
||||
|
||||
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
|
||||
// int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors)
|
||||
// Simplified function call of the above:
|
||||
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
|
||||
// int Max_Secs, DP target_sumrule, bool refine)
|
||||
Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_GeneralState_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
char* Ix2filenameprefix;
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par_Prepare executable: " << endl;
|
||||
cout << endl << "This function prepares an ABACUS++ parallel mode run, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Ix2filenameprefix = argv[n++];
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
//kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_GeneralState_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
|
||||
// Read the Ix2 from the file:
|
||||
Vect<int> Ix2_input(N);
|
||||
ifstream Ix2_input_file;
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
/*
|
||||
filenamestrstream << ".Ix2";
|
||||
string filenamestr = filenamestrstream.str();
|
||||
const char* filename_Cstr = filenamestr.c_str();
|
||||
Ix2_input_file.open(filename_Cstr);
|
||||
if (Ix2_input_file.fail()) {
|
||||
cout << filename_Cstr << endl;
|
||||
JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
Ix2_input_file >> Ix2_input[i];
|
||||
//cout << i << "\t" << Ix2_input[i] << endl;
|
||||
}
|
||||
|
||||
// Define the AveragingState
|
||||
LiebLin_Bethe_State AveragingState(c_int, L, N);
|
||||
AveragingState.Ix2 = Ix2_input;
|
||||
//AveragingState.Compute_All(true);
|
||||
*/
|
||||
|
||||
// Split up thread list into chunks, one per processor
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_GeneralState_par_Run.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, Max_Secs, paralevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
char* Ix2filenameprefix;
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
//cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Ix2filenameprefix = argv[n++];
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
//kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
Max_Secs = atoi(argv[n++]);
|
||||
// supercycle_time = atoi(argv[n++]);
|
||||
//}
|
||||
|
||||
//DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= 120) JSCerror("Please allow more time in LiebLin_DSF_par_Run.");
|
||||
|
||||
int Max_Secs_used = Max_Secs - 120;
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank_here = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors_here = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
// Read the Ix2 from the file:
|
||||
Vect<int> Ix2_input(N);
|
||||
ifstream Ix2_input_file;
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
filenamestrstream << ".Ix2";
|
||||
string filenamestr = filenamestrstream.str();
|
||||
const char* filename_Cstr = filenamestr.c_str();
|
||||
Ix2_input_file.open(filename_Cstr);
|
||||
if (Ix2_input_file.fail()) {
|
||||
cout << filename_Cstr << endl;
|
||||
JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
Ix2_input_file >> Ix2_input[i];
|
||||
//cout << i << "\t" << Ix2_input[i] << endl;
|
||||
}
|
||||
|
||||
// Now define the AveragingState
|
||||
LiebLin_Bethe_State AveragingState(c_int, L, N);
|
||||
AveragingState.Ix2 = Ix2_input;
|
||||
AveragingState.Compute_All(true);
|
||||
|
||||
|
||||
Vect<int> rank (paralevel);
|
||||
Vect<int> nr_processors (paralevel);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank[i] = rank_lower_paralevels[i];
|
||||
nr_processors[i] = nr_processors_lower_paralevels[i];
|
||||
}
|
||||
rank[paralevel-1] = rank_here;
|
||||
nr_processors[paralevel-1] = nr_processors_here;
|
||||
|
||||
if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
|
||||
//while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
|
||||
if (Max_Secs_used > 0) {
|
||||
|
||||
// Barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
|
||||
// supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
char* Ix2filenameprefix;
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par_Wrapup executable: " << endl;
|
||||
cout << endl << "This function wraps up an ABACUS++ parallel mode run." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Ix2filenameprefix = argv[n++];
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
//kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
// Read the Ix2 from the file:
|
||||
Vect<int> Ix2_input(N);
|
||||
ifstream Ix2_input_file;
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
/*
|
||||
filenamestrstream << ".Ix2";
|
||||
string filenamestr = filenamestrstream.str();
|
||||
const char* filename_Cstr = filenamestr.c_str();
|
||||
Ix2_input_file.open(filename_Cstr);
|
||||
if (Ix2_input_file.fail()) {
|
||||
cout << filename_Cstr << endl;
|
||||
JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
Ix2_input_file >> Ix2_input[i];
|
||||
//cout << i << "\t" << Ix2_input[i] << endl;
|
||||
}
|
||||
|
||||
// Define the AveragingState
|
||||
LiebLin_Bethe_State AveragingState(c_int, L, N);
|
||||
AveragingState.Ix2 = Ix2_input;
|
||||
//AveragingState.Compute_All(true);
|
||||
*/
|
||||
|
||||
// Digest files into a unique one for the latest paralevel:
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF.cc
|
||||
|
||||
Purpose: main function for ABACUS++ for LiebLin gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 13) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_MosesState executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF_MosesState d 1.0 100.0 100 50 -30 20 0 200 600 1.0 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 13), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int Nl = atoi(argv[5]);
|
||||
//int Nr = N - Nl;
|
||||
int DIl = atoi(argv[6]);
|
||||
int DIr = atoi(argv[7]);
|
||||
int iKmin = atoi(argv[8]);
|
||||
int iKmax = atoi(argv[9]);
|
||||
//DP kBT = atof(argv[7]);
|
||||
int Max_Secs = atoi(argv[10]);
|
||||
DP target_sumrule = atof(argv[11]);
|
||||
bool refine = (atoi(argv[12]) == 1);
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
//cout << MosesState << endl;
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
// Compute the correlation:
|
||||
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L;
|
||||
int N, Nl, DIl, DIr, iKmin, iKmax, Max_Secs, supercycle_time;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
DP kBT = 0.0; // dummy
|
||||
|
||||
if (argc != 12) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_MosesState_par executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "mpiexec -np 8 LiebLin_DSF_MosesState_par d 1.0 100.0 100 50 -30 20 -400 400 3600 600" << endl << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // (argc == 11) correct nr of arguments
|
||||
whichDSF = *argv[1];
|
||||
c_int = atof(argv[2]);
|
||||
L = atof(argv[3]);
|
||||
N = atoi(argv[4]);
|
||||
Nl = atoi(argv[5]);
|
||||
DIl = atoi(argv[6]);
|
||||
DIr = atoi(argv[7]);
|
||||
iKmin = atoi(argv[8]);
|
||||
iKmax = atoi(argv[9]);
|
||||
Max_Secs = atoi(argv[10]);
|
||||
supercycle_time = atoi(argv[11]);
|
||||
}
|
||||
|
||||
//DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
|
||||
|
||||
if (rank == 0)
|
||||
// Split up thread list into chunks, one per processor
|
||||
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, supercycle_time, target_sumrule, refine, rank, nr_processors);
|
||||
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time, target_sumrule, refine, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
|
||||
if (rank == 0)
|
||||
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L;
|
||||
int N, Nl, DIl, DIr, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
DP kBT = 0.0; // dummy
|
||||
|
||||
if (argc < 12) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Prepare executable: " << endl;
|
||||
cout << endl << "This function prepares an ABACUS++ parallel mode run, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Nl = atoi(argv[n++]);
|
||||
DIl = atoi(argv[n++]);
|
||||
DIr = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 12 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_MosesState_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
|
||||
// Split up thread list into chunks, one per processor
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L;
|
||||
int N, Nl, DIl, DIr, iKmin, iKmax, Max_Secs, supercycle_time, paralevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
DP kBT = 0.0; // dummy
|
||||
|
||||
if (argc < 13) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Run executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Nl = atoi(argv[n++]);
|
||||
DIl = atoi(argv[n++]);
|
||||
DIr = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 13 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
Max_Secs = atoi(argv[n++]);
|
||||
supercycle_time = atoi(argv[n++]);
|
||||
//}
|
||||
|
||||
//DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par_Run.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank_here = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors_here = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
//cout << "rank " << rank_here << " out of " << nr_processors_here << " ready to go." << endl;
|
||||
|
||||
Vect<int> rank (paralevel);
|
||||
Vect<int> nr_processors (paralevel);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank[i] = rank_lower_paralevels[i];
|
||||
nr_processors[i] = nr_processors_lower_paralevels[i];
|
||||
}
|
||||
rank[paralevel-1] = rank_here;
|
||||
nr_processors[paralevel-1] = nr_processors_here;
|
||||
|
||||
if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
//cout << "rank " << rank_here << " out of " << nr_processors_here << " waiting at barrier." << endl;
|
||||
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
|
||||
while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
|
||||
|
||||
//if (rank == 0)
|
||||
// Split up thread list into chunks, one per processor
|
||||
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
|
||||
//if (rank == 0)
|
||||
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_MosesState_par_Wrapup.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L;
|
||||
int N, Nl, DIl, DIr, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
DP kBT = 0.0; // dummy
|
||||
|
||||
if (argc < 12) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Wrapup executable: " << endl;
|
||||
cout << endl << "This function wraps up an ABACUS++ parallel mode run." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Nl = atoi(argv[n++]);
|
||||
DIl = atoi(argv[n++]);
|
||||
DIr = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 12 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_MosesState_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
|
||||
// Digest files into a unique one for the latest paralevel:
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_over_Ensemble.cc
|
||||
|
||||
Purpose: main function for ABACUS++T for LiebLin gas, averaging over an Ensemble.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
//cout << "int nstates \t\t\t Number of states to be considered in the ensemble" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
//cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 0.56 10 600 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
//int nstates_req = atoi(argv[8]);
|
||||
int Max_Secs = atoi(argv[8]);
|
||||
bool refine = (atoi(argv[9]) == 1);
|
||||
|
||||
// Start by constructing (or loading) the state ensemble.
|
||||
|
||||
LiebLin_Diagonal_State_Ensemble ensemble;
|
||||
|
||||
stringstream ensfilestrstream;
|
||||
//ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
|
||||
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
|
||||
string ensfilestr = ensfilestrstream.str();
|
||||
const char* ensfile_Cstr = ensfilestr.c_str();
|
||||
|
||||
if (!refine) { // Construct the state ensemble
|
||||
//ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT, nstates_req);
|
||||
ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT);
|
||||
ensemble.Save(ensfile_Cstr); // Save the ensemble
|
||||
}
|
||||
|
||||
else { // load the ensemble data
|
||||
ensemble.Load(c_int, L, N, ensfile_Cstr);
|
||||
}
|
||||
|
||||
// Now perform the DSF calculation over each state in the ensemble, distributing the time according to the weight
|
||||
|
||||
for (int ns = 0; ns < ensemble.nstates; ++ns) {
|
||||
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
|
||||
//int Max_Secs, DP target_sumrule, bool refine, int rank, int nr_processors)
|
||||
//Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, int(Max_Secs * ensemble.weight[ns]), 1.0e+6, refine, 0, 1);
|
||||
Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, int(Max_Secs * ensemble.weight[ns]), 1.0e+6, refine);
|
||||
}
|
||||
|
||||
// Evaluate the f-sumrule
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
Data_File_Name (FSR_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
FSR_stringstream << "_ns_" << ensemble.nstates << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
|
||||
DP Chem_Pot = 0.0;
|
||||
|
||||
Evaluate_F_Sumrule (whichDSF, c_int, L, N, kBT, ensemble.nstates, Chem_Pot, iKmin, iKmax, FSR_Cstr);
|
||||
|
||||
|
||||
} // correct nr of arguments
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_over_Ensemble_par.cc
|
||||
|
||||
Purpose: main function for ABACUS for LiebLin gas, averaging over an Ensemble, parallel implementation.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
//cout << "int nstates \t\t\t Number of states to be considered in the ensemble" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
//cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 0.56 10 600 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
//int nstates_req = atoi(argv[8]);
|
||||
int Max_Secs = atoi(argv[8]);
|
||||
bool refine = (atoi(argv[9]) == 1);
|
||||
|
||||
if (refine == false) JSCerror("Please run the serial version of LiebLin_DSF_over_Ensemble first.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
|
||||
// Start by constructing (or loading) the state ensemble.
|
||||
|
||||
LiebLin_Diagonal_State_Ensemble ensemble;
|
||||
|
||||
stringstream ensfilestrstream;
|
||||
//ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
|
||||
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
|
||||
string ensfilestr = ensfilestrstream.str();
|
||||
const char* ensfile_Cstr = ensfilestr.c_str();
|
||||
|
||||
if (!refine) { // Construct the state ensemble
|
||||
//ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT, nstates_req);
|
||||
ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT);
|
||||
ensemble.Save(ensfile_Cstr); // Save the ensemble
|
||||
}
|
||||
|
||||
else { // load the ensemble data
|
||||
ensemble.Load(c_int, L, N, ensfile_Cstr);
|
||||
}
|
||||
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now perform the DSF calculation over each state in the ensemble
|
||||
|
||||
/* Original implementation: Scan always called serially. Superseded by version below, using successive parallel scans on each state in the ensemble.
|
||||
int nDSFperproc = ensemble.nstates/nr_processors + 1;
|
||||
//if (ensemble.nstates % nr_processors) JSCerror("Use nr_processors * integer multiple == ensemble.nstates in LiebLin_DSF_over_Ensemble_par.");
|
||||
|
||||
// Processor with rank r does all
|
||||
|
||||
int ns;
|
||||
int Max_Secs_used = Max_Secs/nDSFperproc;
|
||||
|
||||
for (int ir = 0; ir < nDSFperproc; ++ir) {
|
||||
ns = rank + ir * nr_processors;
|
||||
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
|
||||
//int Max_Secs, DP target_sumrule, bool refine, int rank, int nr_processors)
|
||||
if (ns < ensemble.nstates) {
|
||||
//cout << "Processor rank " << rank << " going for ns = " << ns << " out of " << ensemble.nstates << endl;
|
||||
Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, Max_Secs_used, 1.0e+6, refine, 0, 1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Version 2013 04 24:
|
||||
// Makes use of a parallel scan for each state in the ensemble, in succession.
|
||||
// Code is simple adaptation of LiebLin_DSF_par executable code.
|
||||
|
||||
int Max_Secs_used = Max_Secs/ensemble.nstates;
|
||||
|
||||
DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs_used <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par.");
|
||||
|
||||
// Main loop over ensemble:
|
||||
for (int ns = 0; ns < ensemble.nstates; ++ns) {
|
||||
|
||||
tstart = MPI::Wtime();
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
string defaultScanStatename = ensemble.state[ns].label;
|
||||
|
||||
while (tnow - tstart < Max_Secs_used - supercycle_time) { // space for one more supercycle
|
||||
|
||||
if (rank == 0)
|
||||
// Split up thread list into chunks, one per processor
|
||||
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
|
||||
//supercycle_time, target_sumrule, refine, rank, nr_processors);
|
||||
Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, supercycle_time, 1.0e+6, refine, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
|
||||
if (rank == 0)
|
||||
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
} // for ns
|
||||
|
||||
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
|
||||
// Final wrapup of the data
|
||||
if (rank == 0) {
|
||||
|
||||
// Evaluate the f-sumrule
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
Data_File_Name (FSR_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
FSR_stringstream << "_ns_" << ensemble.nstates << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
|
||||
DP Chem_Pot = 0.0;
|
||||
|
||||
Evaluate_F_Sumrule (whichDSF, c_int, L, N, kBT, ensemble.nstates, Chem_Pot, iKmin, iKmax, FSR_Cstr);
|
||||
}
|
||||
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
} // correct nr of arguments
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, Max_Secs, supercycle_time;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "mpiexec -np 8 LiebLin_DSF_MosesState_par d 1.0 100.0 100 -400 400 0.0 3600 600" << endl << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // (argc == 9) correct nr of arguments
|
||||
whichDSF = *argv[1];
|
||||
c_int = atof(argv[2]);
|
||||
L = atof(argv[3]);
|
||||
N = atoi(argv[4]);
|
||||
iKmin = atoi(argv[5]);
|
||||
iKmax = atoi(argv[6]);
|
||||
kBT = atof(argv[7]);
|
||||
Max_Secs = atoi(argv[8]);
|
||||
supercycle_time = atoi(argv[9]);
|
||||
}
|
||||
|
||||
//DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
|
||||
|
||||
if (rank == 0)
|
||||
// Split up thread list into chunks, one per processor
|
||||
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
|
||||
supercycle_time, target_sumrule, refine, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
|
||||
if (rank == 0)
|
||||
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par_Prepare executable: " << endl;
|
||||
cout << endl << "This function prepares an ABACUS++ parallel mode run, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
// Split up thread list into chunks, one per processor
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par_Run.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, Max_Secs, paralevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par_Run executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "mpiexec -np 8 LiebLin_DSF_par_Run d 1.0 100.0 100 0 400 0.0 1 3600" << endl << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Run.");
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
Max_Secs = atoi(argv[n++]);
|
||||
|
||||
if (Max_Secs < 120) JSCerror("Please allow more time in LiebLin_DSF_par_Run.");
|
||||
|
||||
int Max_Secs_used = Max_Secs - 120;
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank_here = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors_here = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
Vect<int> rank (paralevel);
|
||||
Vect<int> nr_processors (paralevel);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank[i] = rank_lower_paralevels[i];
|
||||
nr_processors[i] = nr_processors_lower_paralevels[i];
|
||||
}
|
||||
rank[paralevel-1] = rank_here;
|
||||
nr_processors[paralevel-1] = nr_processors_here;
|
||||
|
||||
if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
if (Max_Secs_used > 0) { // space for 2 minutes safety
|
||||
|
||||
// Barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
|
||||
Max_Secs_used, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
}
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par_Wrapup.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare or Wrapup
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par_Wrapup executable: " << endl;
|
||||
cout << endl << "This function wraps up an ABACUS++ parallel mode run." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Wrapup.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
// Digest files into a unique one for the latest paralevel:
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_tester.cc
|
||||
|
||||
Purpose: allows for Ix2 manipulations (user-prompted) for LiebLin gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 6) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF_tester d 1.0 100.0 100 0.56 " << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 6), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
DP kBT = atof(argv[5]);
|
||||
|
||||
//if (whichDSF != 'd') JSCerror("Other options not implemented yet in finite T Scan_LiebLin");
|
||||
|
||||
// Delta is the number of sites involved in the smoothing of the entropy
|
||||
//int Delta = int(sqrt(N))/2;//6;//N/20;
|
||||
|
||||
// Construct the finite-size saddle-point state:
|
||||
//LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT, Delta);
|
||||
LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
|
||||
spstate.Compute_All(true);
|
||||
|
||||
LiebLin_Bethe_State estate = spstate;
|
||||
if (whichDSF == 'o') estate = Remove_Particle_at_Center (spstate);
|
||||
else if (whichDSF == 'g') estate = Add_Particle_at_Center (spstate);
|
||||
if (whichDSF != 'd') estate.Compute_All(true);
|
||||
cout << estate << endl;
|
||||
Vect<int> OriginIx2 = estate.Ix2;
|
||||
|
||||
int Ix2old, Ix2new;
|
||||
int again = 0;
|
||||
string label_req;
|
||||
do {
|
||||
//cout << "Substitute Ix2: which for which ?" << endl;
|
||||
//cin >> Ix2old >> Ix2new;
|
||||
//for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new;
|
||||
//estate.Ix2.QuickSort();
|
||||
cout << "Which label should the exc state be set to?" << endl;
|
||||
cin >> label_req;
|
||||
estate.Set_to_Label(label_req, OriginIx2);
|
||||
estate.Compute_All(false);
|
||||
cout << spstate << endl;
|
||||
cout << estate;
|
||||
if (whichDSF == 'd')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Density_ME(spstate, estate))) << endl;
|
||||
else if (whichDSF == 'o')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(estate, spstate))) << endl;
|
||||
else if (whichDSF == 'g')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(spstate, estate))) << endl;
|
||||
|
||||
//cout << "Another try ? (1 == yes, 0 == no)" << endl;
|
||||
again = 1;
|
||||
cin >> again;
|
||||
} while (again != 0);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_tester.cc
|
||||
|
||||
Purpose: allows for Ix2 manipulations (user-prompted) for LiebLin gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 6) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF_tester d 1.0 100.0 100 0.56 " << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 6), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
DP kBT = atof(argv[5]);
|
||||
|
||||
//if (whichDSF != 'd') JSCerror("Other options not implemented yet in finite T Scan_LiebLin");
|
||||
|
||||
// Delta is the number of sites involved in the smoothing of the entropy
|
||||
//int Delta = int(sqrt(N))/2;//6;//N/20;
|
||||
|
||||
// Construct the finite-size saddle-point state:
|
||||
//LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT, Delta);
|
||||
LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
|
||||
spstate.Compute_All(true);
|
||||
|
||||
LiebLin_Bethe_State estate = spstate;
|
||||
if (whichDSF == 'o') estate = Remove_Particle_at_Center (spstate);
|
||||
else if (whichDSF == 'g') estate = Add_Particle_at_Center (spstate);
|
||||
if (whichDSF != 'd') estate.Compute_All(true);
|
||||
cout << estate << endl;
|
||||
Vect<int> OriginIx2 = estate.Ix2;
|
||||
|
||||
int Ix2old, Ix2new;
|
||||
int again = 0;
|
||||
string label_req;
|
||||
do {
|
||||
cout << "Substitute Ix2: which for which ?" << endl;
|
||||
cin >> Ix2old >> Ix2new;
|
||||
for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new;
|
||||
estate.Ix2.QuickSort();
|
||||
//cout << "Which label should the exc state be set to?" << endl;
|
||||
//cin >> label_req;
|
||||
//estate.Set_to_Label(label_req, OriginIx2);
|
||||
estate.Compute_All(false);
|
||||
cout << spstate << endl;
|
||||
cout << estate;
|
||||
if (whichDSF == 'd')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Density_ME(spstate, estate))) << endl;
|
||||
else if (whichDSF == 'o')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(estate, spstate))) << endl;
|
||||
else if (whichDSF == 'g')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(spstate, estate))) << endl;
|
||||
|
||||
cout << "Another try ? (1 == yes, 0 == no)" << endl;
|
||||
again = 1;
|
||||
cin >> again;
|
||||
} while (again != 0);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Data_Daemon.cc
|
||||
|
||||
Purpose: Produces sets of data files for correlations.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 11) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Data_Daemon executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int_max \t\t Largest value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "int Nc \t\t number of steps in interaction value" << endl;
|
||||
cout << "int cfact \t\t dividing factor (each new interaction value if 1/cfact times the previous)" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Max_Hrs \t\t Allowed computational time: (in hours)" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
int ia = 1;
|
||||
char whichDSF = *argv[ia++];
|
||||
DP c_int_max = atof(argv[ia++]);
|
||||
int Nc = atoi(argv[ia++]);
|
||||
int cfact = atoi(argv[ia++]);
|
||||
DP L = atof(argv[ia++]);
|
||||
int N = atoi(argv[ia++]);
|
||||
int iKmin = atoi(argv[ia++]);
|
||||
int iKmax = atoi(argv[ia++]);
|
||||
DP kBT = atof(argv[ia++]);
|
||||
int Max_Hrs = atoi(argv[ia++]);
|
||||
|
||||
// Individual computations are split into chuncks of Max_Hrs/(Nc * 4)
|
||||
//int Max_Secs = (Max_Hrs * 900)/Nc;
|
||||
int Max_Secs = (Max_Hrs * 2700)/Nc; // to minimize wrapping up & restarting time
|
||||
|
||||
cout << "Data daemon will use chunks of " << Max_Secs << " seconds." << endl;
|
||||
|
||||
//clock_t StartTime = clock();
|
||||
double StartTime = omp_get_wtime();
|
||||
|
||||
//clock_t ActualTime = StartTime;
|
||||
double ActualTime = omp_get_wtime();
|
||||
|
||||
DP c_int;
|
||||
DP target_sumrule = 1.0;
|
||||
|
||||
//while (double(ActualTime - StartTime)/CLOCKS_PER_SEC < double(3600 * Max_Hrs - Max_Secs)) {
|
||||
while (ActualTime - StartTime < double(3600 * Max_Hrs - Max_Secs)) {
|
||||
|
||||
Vect<DP> srsat(0.0, Nc);
|
||||
Vect<bool> refine(false, Nc);
|
||||
DP srmin = 1.0;
|
||||
int icmin = 0;
|
||||
|
||||
// Determine which correlation has the worst sum rule:
|
||||
for (int ic = 0; ic < Nc; ++ic) {
|
||||
c_int = c_int_max/pow(cfact, ic);
|
||||
stringstream SRC_stringstream; string SRC_string;
|
||||
Data_File_Name (SRC_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
SRC_stringstream << ".src";
|
||||
SRC_string = SRC_stringstream.str(); const char* SRC_Cstr = SRC_string.c_str();
|
||||
|
||||
fstream srcfile;
|
||||
srcfile.open(SRC_Cstr, fstream::in);
|
||||
if (srcfile.fail()) {
|
||||
srsat[ic] = 0.0;
|
||||
refine[ic] = false;
|
||||
}
|
||||
else {
|
||||
srcfile >> srsat[ic];
|
||||
refine[ic] = true;
|
||||
}
|
||||
if (srsat[ic] < srmin) {
|
||||
srmin = srsat[ic];
|
||||
icmin = ic;
|
||||
}
|
||||
srcfile.close();
|
||||
|
||||
} // for ic
|
||||
|
||||
cout << "srsat min found: " << srmin << "\t for c = " << c_int_max/pow(cfact, icmin) << ". Now refining this."
|
||||
//<< " Time left: " << 3600* Max_Hrs - (ActualTime - StartTime)/CLOCKS_PER_SEC << " seconds." << endl;
|
||||
<< " Time left: " << 3600* Max_Hrs - (ActualTime - StartTime) << " seconds." << endl;
|
||||
|
||||
// Improve the icmin calculation by one chunk:
|
||||
Scan_LiebLin (whichDSF, c_int_max/pow(cfact, icmin), L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine[icmin]);
|
||||
|
||||
//ActualTime = clock();
|
||||
ActualTime = omp_get_wtime();
|
||||
|
||||
} // while there is time
|
||||
|
||||
cout << "Wrapping up, time's up." << endl;
|
||||
|
||||
} // else if arguments given OK
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Data_Daemon_Nscaling.cc
|
||||
|
||||
Purpose: Produces sets of data files for correlations, increasing system size at fixed c and momentum window.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Data_Daemon_Nscaling executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
//cout << "int Nc \t\t number of steps in interaction value" << endl;
|
||||
cout << "int Nstep \t\t\t Steps to be taken in number of particles: use positive integer values only. Filling will be set to 1 (L == N)" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over (in units of N == Nstep): recommended values: 0 and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "int Max_minutes \t\t Allowed computational time: (in minutes)" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
int ia = 1;
|
||||
char whichDSF = *argv[ia++];
|
||||
DP c_int = atof(argv[ia++]);
|
||||
int Nstep = atoi(argv[ia++]);
|
||||
int iKmin_Nstep = atoi(argv[ia++]);
|
||||
int iKmax_Nstep = atoi(argv[ia++]);
|
||||
DP kBT = atof(argv[ia++]);
|
||||
DP target_sumrule = atof(argv[ia++]);
|
||||
int Max_minutes = atoi(argv[ia++]);
|
||||
|
||||
|
||||
//clock_t StartTime = clock();
|
||||
double StartTime = omp_get_wtime();
|
||||
|
||||
//clock_t ActualTime = StartTime;
|
||||
double ActualTime = omp_get_wtime();
|
||||
|
||||
int Secs_left = 60* Max_minutes;
|
||||
|
||||
int iN = 0;
|
||||
|
||||
while (Secs_left > 0) {
|
||||
|
||||
iN += 1;
|
||||
int N = Nstep * iN;
|
||||
DP L = N;
|
||||
int iKmin = iKmin_Nstep * iN;
|
||||
int iKmax = iKmax_Nstep * iN;
|
||||
DP srsat = 0.0;
|
||||
bool refine = false;
|
||||
|
||||
stringstream SRC_stringstream; string SRC_string;
|
||||
Data_File_Name (SRC_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
SRC_stringstream << ".src";
|
||||
SRC_string = SRC_stringstream.str(); const char* SRC_Cstr = SRC_string.c_str();
|
||||
|
||||
fstream srcfile;
|
||||
srcfile.open(SRC_Cstr, fstream::in);
|
||||
if (srcfile.fail()) {
|
||||
srsat = 0.0;
|
||||
refine = false;
|
||||
}
|
||||
else {
|
||||
srcfile >> srsat;
|
||||
refine = true;
|
||||
}
|
||||
srcfile.close();
|
||||
|
||||
// Improve the icmin calculation by one chunk:
|
||||
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Secs_left, target_sumrule, refine);
|
||||
|
||||
ActualTime = clock();
|
||||
|
||||
//Secs_left = int(60*Max_minutes - double(ActualTime - StartTime)/CLOCKS_PER_SEC);
|
||||
Secs_left = int(60*Max_minutes - (ActualTime - StartTime));
|
||||
|
||||
cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl;
|
||||
|
||||
} // while there is time
|
||||
|
||||
} // else if arguments given OK
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Fourier_to_Qsqx.cc
|
||||
|
||||
Purpose: Compute the Q(x)^2 expectation value for LiebLin, where Q(x) = \int_0^x dx \rho(x).
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Fourier_to_Qsqx executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 9), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int Npts_x = atoi(argv[8]);
|
||||
// Force Npts_x
|
||||
//Npts_x = L;
|
||||
|
||||
if (whichDSF != 'd') JSCerror("Must use whichDSF == d in LiebLin_Fourier_ssf_to_Qsqx");
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(RAW_Cstr);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << RAW_Cstr << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
// We also read the f-sumrule file, to correct for missing intensity.
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
FSR_stringstream << prefix << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
ifstream FSR_infile;
|
||||
FSR_infile.open(FSR_Cstr);
|
||||
if (FSR_infile.fail()) {
|
||||
cout << FSR_Cstr << endl;
|
||||
JSCerror("Could not open FSR_infile... ");
|
||||
}
|
||||
|
||||
stringstream SFT_stringstream; string SFT_string;
|
||||
SFT_stringstream << prefix << ".Qsqx";
|
||||
SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str();
|
||||
ofstream SFT_outfile;
|
||||
SFT_outfile.open(SFT_Cstr);
|
||||
if (SFT_outfile.fail()) JSCerror("Could not open SFT_outfile... ");
|
||||
|
||||
// First compute the static structure factor from the RAW data:
|
||||
|
||||
Vect_DP SSF(0.0, iKmax - iKmin + 1);
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
if (iK >= iKmin && iK <= iKmax) {
|
||||
SSF[iK - iKmin] += FF * FF;
|
||||
}
|
||||
}
|
||||
RAW_infile.close();
|
||||
|
||||
// Reset proper normalization:
|
||||
DP normalization = twoPI * L;
|
||||
for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) SSF[iK] *= normalization/twoPI; // twoPI from integral over omega
|
||||
|
||||
|
||||
// Now define real-space coordinates: between 0 and L/2
|
||||
Vect_DP xlattice(Npts_x);
|
||||
for (int i = 0; i < Npts_x; ++i) xlattice[i] = (i + 0.5) * 0.5* L/Npts_x;
|
||||
|
||||
// Now the correlation at x:
|
||||
Vect_DP FT(0.0, Npts_x);
|
||||
|
||||
DP pioverL = PI/L;
|
||||
|
||||
// Fourier transform:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
for (int iK = 1; iK <= iKmax; ++iK) {
|
||||
FT[ix] += SSF[iK - iKmin] * pow(sin(pioverL * iK * xlattice[ix])/iK, 2.0);
|
||||
}
|
||||
// Reset proper normalization: 1/L from space FT,
|
||||
FT[ix] *= 2.0*L/(PI * PI);
|
||||
|
||||
// Outside of window iKmin, iKmax, we take the DSF to be a constant with delta function
|
||||
// at free energy k^2, so DSF = 2\pi N/L \delta(\omega - k^2) (to fit f-sumrule)
|
||||
// so SSF becomes N/L.
|
||||
// We thus need to correct above by adding
|
||||
// \frac{1}{L} \sum_{-\infty}^{iKmin - 1} SSF e^{ikx} + \frac{1}{L} \sum_{iKmax + 1}^\infty SSF e^{ikx}
|
||||
// Resumming carefully:
|
||||
//FTre[ix] += (sin(twopioverL * (iKmin - 0.5) * xlattice[ix]) - sin(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
//* N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
//FTim[ix] += (-cos(twopioverL * (iKmin - 0.5) * xlattice[ix]) + cos(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
//* N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
}
|
||||
|
||||
|
||||
// Output to file:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
if (ix > 0) SFT_outfile << endl;
|
||||
//SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix];
|
||||
SFT_outfile << xlattice[ix]/L << "\t" << FT[ix];
|
||||
}
|
||||
|
||||
SFT_outfile.close();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Fourier_to_t_equal_x.cc
|
||||
|
||||
Purpose: Fourier transform to static space correlator for LiebLin.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int Npts_t \t Number of points in time for the Fourier transform" << endl;
|
||||
cout << "DP t_max \t Max time to be used" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int Npts_t = atoi(argv[8]);
|
||||
DP t_max = atof(argv[9]);
|
||||
|
||||
// Momentum business: use symmetry
|
||||
if (iKmin != 0) JSCerror("LiebLin_Fourier_to_t_equal_x only implemented for raw files with iKmin == 0.");
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(RAW_Cstr);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << RAW_Cstr << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
// We also read the f-sumrule file, to correct for missing intensity.
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
FSR_stringstream << prefix << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
ifstream FSR_infile;
|
||||
FSR_infile.open(FSR_Cstr);
|
||||
if (FSR_infile.fail()) {
|
||||
cout << FSR_Cstr << endl;
|
||||
JSCerror("Could not open FSR_infile... ");
|
||||
}
|
||||
|
||||
stringstream SFT_stringstream; string SFT_string;
|
||||
SFT_stringstream << prefix << ".tft";
|
||||
SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str();
|
||||
ofstream SFT_outfile;
|
||||
SFT_outfile.open(SFT_Cstr);
|
||||
if (SFT_outfile.fail()) JSCerror("Could not open TFT_outfile... ");
|
||||
|
||||
// First compute the static structure factor from the RAW data:
|
||||
|
||||
Vect_DP TSF(0.0, Npts_t);
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
// Now define time coordinates: between 0 and t_max
|
||||
Vect_DP tlattice(Npts_t);
|
||||
for (int i = 0; i < Npts_t; ++i) tlattice[i] = (i + 0.5) * t_max/Npts_t;
|
||||
|
||||
// Now the correlation at t:
|
||||
Vect<complex<DP> > FT(0.0, Npts_t);
|
||||
Vect_DP FTre(0.0, Npts_t);
|
||||
Vect_DP FTim(0.0, Npts_t);
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
if (iK == 0)
|
||||
for (int it = 0; it < Npts_t; ++it)
|
||||
FT[it] += FF * FF * exp(II * omega * tlattice[it]);
|
||||
else
|
||||
for (int it = 0; it < Npts_t; ++it)
|
||||
FT[it] += 2.0 * FF * FF * exp(II * omega * tlattice[it]);
|
||||
}
|
||||
RAW_infile.close();
|
||||
|
||||
// Reset proper normalization:
|
||||
for (int it = 0; it < Npts_t; ++it) {
|
||||
FTre[it] = real(FT[it]);
|
||||
FTim[it] = imag(FT[it]);
|
||||
}
|
||||
|
||||
// Output to file:
|
||||
for (int it = 0; it < Npts_t; ++it) {
|
||||
if (it > 0) SFT_outfile << endl;
|
||||
SFT_outfile << tlattice[it] << "\t" << FTre[it] << "\t" << FTim[it];
|
||||
}
|
||||
|
||||
SFT_outfile.close();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Fourier_to_t_equal_x.cc
|
||||
|
||||
Purpose: Fourier transform to static space correlator for LiebLin.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
|
||||
//cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "RAW file name" << endl;
|
||||
cout << "int Npts_t \t Number of points in time for the Fourier transform" << endl;
|
||||
cout << "DP t_max \t Max time to be used" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
//DP kBT = atof(argv[7]);
|
||||
char* rawfilename = argv[7];
|
||||
int Npts_t = atoi(argv[8]);
|
||||
DP t_max = atof(argv[9]);
|
||||
|
||||
// Momentum business: use symmetry
|
||||
if (iKmin != 0) JSCerror("LiebLin_Fourier_to_t_equal_x only implemented for raw files with iKmin == 0.");
|
||||
|
||||
ifstream RAW_infile;
|
||||
//RAW_infile.open(RAW_Cstr);
|
||||
RAW_infile.open(rawfilename);
|
||||
if (RAW_infile.fail()) {
|
||||
//cout << RAW_Cstr << endl;
|
||||
cout << rawfilename << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
stringstream SFT_stringstream; string SFT_string;
|
||||
SFT_stringstream << rawfilename << "_tft";
|
||||
SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str();
|
||||
ofstream SFT_outfile;
|
||||
SFT_outfile.open(SFT_Cstr);
|
||||
if (SFT_outfile.fail()) JSCerror("Could not open TFT_outfile... ");
|
||||
|
||||
// First compute the static structure factor from the RAW data:
|
||||
|
||||
Vect_DP TSF(0.0, Npts_t);
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
// Now define time coordinates: between 0 and t_max
|
||||
Vect_DP tlattice(Npts_t);
|
||||
for (int i = 0; i < Npts_t; ++i) tlattice[i] = (i + 0.5) * t_max/Npts_t;
|
||||
|
||||
// Now the correlation at t:
|
||||
Vect<complex<DP> > FT(0.0, Npts_t);
|
||||
Vect_DP FTre(0.0, Npts_t);
|
||||
Vect_DP FTim(0.0, Npts_t);
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
if (iK == 0)
|
||||
for (int it = 0; it < Npts_t; ++it)
|
||||
FT[it] += FF * FF * exp(II * omega * tlattice[it]);
|
||||
else
|
||||
for (int it = 0; it < Npts_t; ++it)
|
||||
FT[it] += 2.0 * FF * FF * exp(II * omega * tlattice[it]);
|
||||
}
|
||||
RAW_infile.close();
|
||||
|
||||
// Reset proper normalization:
|
||||
for (int it = 0; it < Npts_t; ++it) {
|
||||
FTre[it] = real(FT[it]);
|
||||
FTim[it] = imag(FT[it]);
|
||||
}
|
||||
|
||||
// Output to file:
|
||||
for (int it = 0; it < Npts_t; ++it) {
|
||||
if (it > 0) SFT_outfile << endl;
|
||||
SFT_outfile << tlattice[it] << "\t" << FTre[it] << "\t" << FTim[it];
|
||||
}
|
||||
|
||||
SFT_outfile.close();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Fourier_to_x_equal_t.cc
|
||||
|
||||
Purpose: Fourier transform to static space correlator for LiebLin.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 9), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int Npts_x = atoi(argv[8]);
|
||||
// Force Npts_x
|
||||
//Npts_x = L;
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(RAW_Cstr);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << RAW_Cstr << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
// We also read the f-sumrule file, to correct for missing intensity.
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
FSR_stringstream << prefix << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
ifstream FSR_infile;
|
||||
FSR_infile.open(FSR_Cstr);
|
||||
if (FSR_infile.fail()) {
|
||||
cout << FSR_Cstr << endl;
|
||||
JSCerror("Could not open FSR_infile... ");
|
||||
}
|
||||
|
||||
stringstream SFT_stringstream; string SFT_string;
|
||||
SFT_stringstream << prefix << ".sft";
|
||||
SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str();
|
||||
ofstream SFT_outfile;
|
||||
SFT_outfile.open(SFT_Cstr);
|
||||
if (SFT_outfile.fail()) JSCerror("Could not open SFT_outfile... ");
|
||||
|
||||
// First compute the static structure factor from the RAW data:
|
||||
|
||||
Vect_DP SSF(0.0, iKmax - iKmin + 1);
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
if (iK >= iKmin && iK <= iKmax) {
|
||||
SSF[iK - iKmin] += FF * FF;
|
||||
}
|
||||
}
|
||||
RAW_infile.close();
|
||||
|
||||
// Reset proper normalization:
|
||||
DP normalization = twoPI * L;
|
||||
for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) SSF[iK] *= normalization/twoPI; // twoPI from integral over omega
|
||||
|
||||
// We now refine the SSF in the following way.
|
||||
// First, we read off the f-sumrule saturation from the FSR file.
|
||||
// Then, we put back the missing weight, assuming that it lives
|
||||
// on the free k^2 dispersion relation (so the DSF is then simply 2\pi N/L \delta(\omega - k^2)).
|
||||
|
||||
Vect_DP FSRsaturated(0.0, iKmax - iKmin + 1);
|
||||
int dummyint;
|
||||
DP dummy;
|
||||
for (int i = iKmin; i <= iKmax; ++i)
|
||||
FSR_infile >> dummyint >> FSRsaturated[i - iKmin] >> dummy;
|
||||
|
||||
FSR_infile.close();
|
||||
|
||||
// Now correct the SSF by the missing piece:
|
||||
//for (int iK = iKmin; iK <= iKmax; ++iK)
|
||||
//SSF[iK - iKmin] += (1.0 - FSRsaturated[iK - iKmin]) * N/L;
|
||||
|
||||
//cout << FSRsaturated << endl;
|
||||
|
||||
//cout << SSF << endl;
|
||||
|
||||
// Now define real-space coordinates: between 0 and L
|
||||
Vect_DP xlattice(Npts_x);
|
||||
for (int i = 0; i < Npts_x; ++i) xlattice[i] = (i + 0.5) * L/Npts_x;
|
||||
|
||||
// Now the correlation at x:
|
||||
Vect_DP FTre(0.0, Npts_x);
|
||||
Vect_DP FTim(0.0, Npts_x);
|
||||
|
||||
DP twopioverL = twoPI/L;
|
||||
|
||||
// Fourier transform:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
for (int iK = iKmin; iK <= iKmax; ++iK) {
|
||||
FTre[ix] += SSF[iK - iKmin] * cos(twopioverL * iK * xlattice[ix]);
|
||||
FTim[ix] += SSF[iK - iKmin] * sin(twopioverL * iK * xlattice[ix]);
|
||||
}
|
||||
// Reset proper normalization: 1/L from space FT,
|
||||
FTre[ix] /= L;
|
||||
FTim[ix] /= L;
|
||||
|
||||
// Outside of window iKmin, iKmax, we take the DSF to be a constant with delta function
|
||||
// at free energy k^2, so DSF = 2\pi N/L \delta(\omega - k^2) (to fit f-sumrule)
|
||||
// so SSF becomes N/L.
|
||||
// We thus need to correct above by adding
|
||||
// \frac{1}{L} \sum_{-\infty}^{iKmin - 1} SSF e^{ikx} + \frac{1}{L} \sum_{iKmax + 1}^\infty SSF e^{ikx}
|
||||
// Resumming carefully:
|
||||
if (whichDSF == 'd') {
|
||||
FTre[ix] += (sin(twopioverL * (iKmin - 0.5) * xlattice[ix]) - sin(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
* N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
FTim[ix] += (-cos(twopioverL * (iKmin - 0.5) * xlattice[ix]) + cos(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
* N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
}
|
||||
}
|
||||
|
||||
// Since iKmax and iKmin are finite, we need to average over an interval of
|
||||
// deltax such that (2\pi/L) iKmax deltax = 2\pi, with deltax == deltaix * L/Npts_x
|
||||
// so deltaix = (Npts_x/L) * (L/iKmax)
|
||||
/*
|
||||
int deltaix = 0*int(Npts_x/(2.0*iKmax));
|
||||
cout << "deltaix = " << deltaix << endl;
|
||||
|
||||
Vect_DP FTreavg(0.0, Npts_x);
|
||||
Vect_DP FTimavg(0.0, Npts_x);
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
for (int ix2 = -deltaix; ix2 < deltaix; ++ix2) {
|
||||
FTreavg[ix] += FTre[JSC::min(JSC::max(0, ix + ix2), Npts_x - 1)];
|
||||
FTimavg[ix] += FTim[JSC::min(JSC::max(0, ix + ix2), Npts_x - 1)];
|
||||
}
|
||||
FTreavg[ix] /= (2*deltaix + 1);
|
||||
FTimavg[ix] /= (2*deltaix + 1);
|
||||
}
|
||||
*/
|
||||
if (whichDSF == 'd') cout << "g2(0) = dE0_dc/L = " << LiebLin_dE0_dc (c_int, L, N)/L << "\t" << LiebLin_dE0_dc (c_int, 2.0*L, 2*N)/(2.0*L) << endl;
|
||||
|
||||
// Output to file:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
if (ix > 0) SFT_outfile << endl;
|
||||
//SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix];
|
||||
SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix];
|
||||
}
|
||||
|
||||
SFT_outfile.close();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Fourier_to_x_equal_t.cc
|
||||
|
||||
Purpose: Fourier transform to static space correlator for LiebLin.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
|
||||
//cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "RAW file name" << endl;
|
||||
cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 9), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
//DP kBT = atof(argv[7]);
|
||||
char* rawfilename = argv[7];
|
||||
int Npts_x = atoi(argv[8]);
|
||||
// Force Npts_x
|
||||
//Npts_x = L;
|
||||
|
||||
//stringstream filenameprefix;
|
||||
//Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
//string prefix = filenameprefix.str();
|
||||
|
||||
//stringstream RAW_stringstream; string RAW_string;
|
||||
//RAW_stringstream << prefix << ".raw";
|
||||
//RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
ifstream RAW_infile;
|
||||
//RAW_infile.open(RAW_Cstr);
|
||||
RAW_infile.open(rawfilename);
|
||||
if (RAW_infile.fail()) {
|
||||
//cout << RAW_Cstr << endl;
|
||||
cout << rawfilename << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
// Define the output file name: use the RAW file name but with different suffix
|
||||
|
||||
stringstream SFT_stringstream; string SFT_string;
|
||||
SFT_stringstream << rawfilename << "_sft";
|
||||
SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str();
|
||||
ofstream SFT_outfile;
|
||||
SFT_outfile.open(SFT_Cstr);
|
||||
if (SFT_outfile.fail()) JSCerror("Could not open SFT_outfile... ");
|
||||
|
||||
// First compute the static structure factor from the RAW data:
|
||||
|
||||
Vect_DP SSF(0.0, iKmax - iKmin + 1);
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
if (iK >= iKmin && iK <= iKmax) {
|
||||
SSF[iK - iKmin] += FF * FF;
|
||||
}
|
||||
}
|
||||
RAW_infile.close();
|
||||
|
||||
// Reset proper normalization:
|
||||
DP normalization = twoPI * L;
|
||||
for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) SSF[iK] *= normalization/twoPI; // twoPI from integral over omega
|
||||
|
||||
|
||||
// Now define real-space coordinates: between 0 and L
|
||||
Vect_DP xlattice(Npts_x);
|
||||
for (int i = 0; i < Npts_x; ++i) xlattice[i] = (i + 0.5) * L/Npts_x;
|
||||
|
||||
// Now the correlation at x:
|
||||
Vect_DP FTre(0.0, Npts_x);
|
||||
Vect_DP FTim(0.0, Npts_x);
|
||||
|
||||
DP twopioverL = twoPI/L;
|
||||
|
||||
// Fourier transform:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
for (int iK = iKmin; iK <= iKmax; ++iK) {
|
||||
FTre[ix] += SSF[iK - iKmin] * cos(twopioverL * iK * xlattice[ix]);
|
||||
FTim[ix] += SSF[iK - iKmin] * sin(twopioverL * iK * xlattice[ix]);
|
||||
}
|
||||
// Reset proper normalization: 1/L from space FT,
|
||||
FTre[ix] /= L;
|
||||
FTim[ix] /= L;
|
||||
|
||||
// Outside of window iKmin, iKmax, we take the DSF to be a constant with delta function
|
||||
// at free energy k^2, so DSF = 2\pi N/L \delta(\omega - k^2) (to fit f-sumrule)
|
||||
// so SSF becomes N/L.
|
||||
// We thus need to correct above by adding
|
||||
// \frac{1}{L} \sum_{-\infty}^{iKmin - 1} SSF e^{ikx} + \frac{1}{L} \sum_{iKmax + 1}^\infty SSF e^{ikx}
|
||||
// Resumming carefully:
|
||||
//if (whichDSF == 'd') {
|
||||
//FTre[ix] += (sin(twopioverL * (iKmin - 0.5) * xlattice[ix]) - sin(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
// * N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
//FTim[ix] += (-cos(twopioverL * (iKmin - 0.5) * xlattice[ix]) + cos(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
// * N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
// Output to file:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
if (ix > 0) SFT_outfile << endl;
|
||||
//SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix];
|
||||
SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix];
|
||||
}
|
||||
|
||||
SFT_outfile.close();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_tester.cc
|
||||
|
||||
Purpose: allows for Ix2 manipulations (user-prompted) for LiebLin gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 8) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 6), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int Nl = atoi(argv[5]);
|
||||
//int Nr = N - Nl;
|
||||
int DIl = atoi(argv[6]);
|
||||
int DIr = atoi(argv[7]);
|
||||
|
||||
if (whichDSF != 'd') JSCerror("Other options not implemented yet in LiebLin_Moses_tester");
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] -= 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
LiebLin_Bethe_State estate = MosesState;
|
||||
cout << MosesState;
|
||||
|
||||
int Ix2old, Ix2new;
|
||||
int again = 0;
|
||||
do {
|
||||
cout << "Substitute Ix2: which for which ?" << endl;
|
||||
cin >> Ix2old >> Ix2new;
|
||||
for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new;
|
||||
estate.Compute_All(false);
|
||||
cout << estate;
|
||||
cout << setprecision(16) << "omega = " << estate.E - MosesState.E << "\t" << exp(real(ln_Density_ME(MosesState, estate))) << endl;
|
||||
cout << "Another try ? (0 == no)" << endl;
|
||||
cin >> again;
|
||||
} while (again != 0);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_RAW_File_stats.cc
|
||||
|
||||
Purpose: Analyzes the distribution of matrix element values in a RAW file,
|
||||
to help with optimization of the scanning procedure.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_RAW_File_Stats executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Aggregate size" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 9), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int AgSize = atoi(argv[8]);
|
||||
|
||||
if (AgSize < 2) JSCerror("Give an aggregate size > 1 in LiebLin_RAW_File_Stats.");
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
Data_File_Name (RAW_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
RAW_stringstream << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(RAW_Cstr);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << RAW_Cstr << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
stringstream STAT_stringstream; string STAT_string;
|
||||
Data_File_Name (STAT_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
STAT_stringstream << ".stat";
|
||||
STAT_string = STAT_stringstream.str(); const char* STAT_Cstr = STAT_string.c_str();
|
||||
|
||||
ofstream STATfile;
|
||||
STATfile.open(STAT_Cstr);
|
||||
if (STATfile.fail()) {
|
||||
cout << STAT_Cstr << endl; JSCerror("Could not open STATfile.");
|
||||
}
|
||||
|
||||
LiebLin_Bethe_State AveragingState = Canonical_Saddle_Point_State (c_int, L, N, whichDSF == 'Z' ? 0.0 : kBT);
|
||||
|
||||
DP Chem_Pot = Chemical_Potential (AveragingState);
|
||||
//DP sumrule_factor = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, fixed_iK, iKneeded);
|
||||
Vect<DP> sumrule_factor(iKmax - iKmin + 1);
|
||||
for (int ik = 0; ik < iKmax - iKmin + 1; ++ik)
|
||||
sumrule_factor[ik] = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, ik, ik);
|
||||
// Normalize by total number of considered momenta
|
||||
DP correction_factor = 1.0/(iKmax - iKmin + 1);
|
||||
if (iKmin <= 0 && iKmax >= 0 && whichDSF == 'd') { // correct for fact that RhoRho is 0 at k = 0
|
||||
sumrule_factor[0] = 0.0;
|
||||
correction_factor = 1.0/(iKmax - iKmin);
|
||||
}
|
||||
|
||||
for (int ik = 0; ik < iKmax - iKmin + 1; ++ik) sumrule_factor[ik] *= correction_factor;
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP ME;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
int nread = 0;
|
||||
|
||||
DP srcont = 0.0;
|
||||
DP abssrcont = 0.0;
|
||||
DP maxsrcont = 0.0;
|
||||
DP totsrcont = 0.0;
|
||||
DP accumulatedsrcont = 0.0;
|
||||
int naccounted = 0;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
|
||||
RAW_infile >> omega >> iK >> ME >> dev >> label;
|
||||
nread++;
|
||||
|
||||
if (iK >= iKmin && iK <= iKmax) {
|
||||
srcont = omega * ME * ME * sumrule_factor[iK - iKmin];
|
||||
abssrcont = fabs(srcont);
|
||||
maxsrcont = JSC::max(maxsrcont, abssrcont);
|
||||
totsrcont += srcont;
|
||||
accumulatedsrcont += srcont;
|
||||
naccounted++;
|
||||
}
|
||||
|
||||
if (naccounted >= AgSize) {
|
||||
STATfile << nread << "\t" << maxsrcont << "\t" << totsrcont/AgSize << "\t" << totsrcont/(AgSize * (maxsrcont > 0.0 ? maxsrcont : 1.0)) << "\t" << accumulatedsrcont << endl;
|
||||
naccounted = 0;
|
||||
maxsrcont = 0.0;
|
||||
totsrcont = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
RAW_infile.close();
|
||||
STATfile.close();
|
||||
}
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_TBA.cc
|
||||
|
||||
Purpose: solves the TBA equations for Lieb-Liniger
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
||||
//if (argc != 7) JSCerror("Wrong number of arguments to 2CBG_ThLim executable. Use c(best to set to 1), nbar, ebar, req_diff, Max_Secs, bool Save_data (0 == false).");
|
||||
if (argc != 6) JSCerror("Wrong number of arguments. Use c(best to set to 1), mu, kBT, req_diff, Max_Secs");
|
||||
|
||||
DP c_int = atof(argv[1]);
|
||||
DP mu = atof(argv[2]);
|
||||
DP kBT = atof(argv[3]);
|
||||
DP req_diff = atof(argv[4]);
|
||||
int Max_Secs = atoi(argv[5]);
|
||||
|
||||
if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
|
||||
if (kBT <= 0.0) JSCerror("Negative T ? Not for the LiebLin gas.");
|
||||
if (Max_Secs < 10) JSCerror("Give more time.");
|
||||
|
||||
//cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
|
||||
|
||||
LiebLin_TBA_Solution solution(c_int, mu, kBT, req_diff, Max_Secs);
|
||||
|
||||
|
||||
cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
|
||||
|
||||
return(0);
|
||||
}
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_TBA_fixed_nbar.cc
|
||||
|
||||
Purpose: solves the TBA equations for Lieb-Liniger
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
||||
//if (argc != 7) JSCerror("Wrong number of arguments to 2CBG_ThLim executable. Use c(best to set to 1), nbar, ebar, req_diff, Max_Secs, bool Save_data (0 == false).");
|
||||
if (argc != 6) JSCerror("Wrong number of arguments. Use c(best to set to 1), nbar, kBT, req_diff, Max_Secs");
|
||||
|
||||
DP c_int = atof(argv[1]);
|
||||
DP nbar = atof(argv[2]);
|
||||
DP kBT = atof(argv[3]);
|
||||
DP req_diff = atof(argv[4]);
|
||||
int Max_Secs = atoi(argv[5]);
|
||||
|
||||
if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
|
||||
if (kBT <= 0.0) JSCerror("Negative T ? Not for the LiebLin gas.");
|
||||
if (Max_Secs < 10) JSCerror("Give more time.");
|
||||
|
||||
//cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
|
||||
|
||||
LiebLin_TBA_Solution solution = LiebLin_TBA_Solution_fixed_nbar (c_int, nbar, kBT, req_diff, Max_Secs);
|
||||
|
||||
cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
|
||||
|
||||
return(0);
|
||||
}
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_TBA_fixed_nbar_ebar.cc
|
||||
|
||||
Purpose: solves the TBA equations for Lieb-Liniger
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 7) JSCerror("Wrong number of arguments. Use c(best to set to 1), nbar, ebar, req_diff, Max_Secs, bool Save_data (0 == false).");
|
||||
|
||||
DP c_int = atof(argv[1]);
|
||||
DP nbar = atof(argv[2]);
|
||||
DP ebar = atof(argv[3]);
|
||||
DP req_diff = atof(argv[4]);
|
||||
int Max_Secs = atoi(argv[5]);
|
||||
bool Save_data = bool(atoi(argv[6]));
|
||||
|
||||
if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
|
||||
if (Max_Secs < 10) JSCerror("Give more time.");
|
||||
|
||||
//cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
|
||||
|
||||
LiebLin_TBA_Solution solution = LiebLin_TBA_Solution_fixed_nbar_ebar(c_int, nbar, ebar, req_diff, Max_Secs);
|
||||
|
||||
cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: ODSLF_DSF.cc
|
||||
|
||||
Purpose: main function for ABACUS++ for spinless fermions related to Heisenberg spin-1/2 chain
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << "Usage of ODSLF_DSF executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "ODSLF_DSF z 1.0 100 40 0 100 600 1.0 0" << endl << endl;
|
||||
}
|
||||
|
||||
else if (argc == 10) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
int Max_Secs = atoi(argv[7]);
|
||||
DP target_sumrule = atof(argv[8]);
|
||||
bool refine = (atoi(argv[9]) == 1);
|
||||
|
||||
Scan_ODSLF (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
else JSCerror("Wrong number of arguments to ODSLF_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Sort_RAW_File.cc
|
||||
|
||||
Purpose: produce a sorted .raw file.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 4) {
|
||||
cout << "Arguments needed: rawfile, whichDSF, whichsorting." << endl;
|
||||
JSCerror("");
|
||||
}
|
||||
|
||||
const char* rawfilename = argv[1];
|
||||
char whichDSF = *argv[2];
|
||||
char whichsorting = *argv[3];
|
||||
|
||||
|
||||
//cout << rawfilename << "\t" << whichDSF << "\t" << whichsorting << endl;
|
||||
Sort_RAW_File (rawfilename, whichsorting, whichDSF);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: RAW_File_stats.cc
|
||||
|
||||
Purpose: Analyzes the distribution of matrix element values in a RAW file,
|
||||
to help with optimization of the scanning procedure.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 3) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of RAW_File_Stats executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << endl << "string RAW file name" << endl;
|
||||
cout << "int Aggregate size" << endl;
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
const char* rawfilename = argv[1];
|
||||
int AgSize = atoi(argv[2]);
|
||||
|
||||
if (AgSize < 2) JSCerror("Give an aggregate size > 1 in LiebLin_RAW_File_Stats.");
|
||||
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(rawfilename);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << rawfilename << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
stringstream STAT_stringstream; string STAT_string;
|
||||
STAT_stringstream << rawfilename << "_AgS_" << AgSize << "_stat";
|
||||
STAT_string = STAT_stringstream.str(); const char* STAT_Cstr = STAT_string.c_str();
|
||||
|
||||
ofstream STATfile;
|
||||
STATfile.open(STAT_Cstr);
|
||||
if (STATfile.fail()) {
|
||||
cout << STAT_Cstr << endl; JSCerror("Could not open STATfile.");
|
||||
}
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP ME;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
int nread = 0;
|
||||
|
||||
DP srcont = 0.0;
|
||||
DP abssrcont = 0.0;
|
||||
DP maxsrcont = 0.0;
|
||||
DP totsrcont = 0.0;
|
||||
DP accumulatedsrcont = 0.0;
|
||||
int naccounted = 0;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
|
||||
RAW_infile >> omega >> iK >> ME >> dev >> label;
|
||||
nread++;
|
||||
|
||||
srcont = ME * ME;
|
||||
abssrcont = fabs(srcont);
|
||||
maxsrcont = JSC::max(maxsrcont, abssrcont);
|
||||
totsrcont += srcont;
|
||||
accumulatedsrcont += srcont;
|
||||
naccounted++;
|
||||
|
||||
if (naccounted >= AgSize) {
|
||||
STATfile << nread << "\t" << maxsrcont << "\t" << totsrcont/AgSize << "\t" << totsrcont/(AgSize * (maxsrcont > 0.0 ? maxsrcont : 1.0)) << "\t" << accumulatedsrcont << endl;
|
||||
naccounted = 0;
|
||||
maxsrcont = 0.0;
|
||||
totsrcont = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
RAW_infile.close();
|
||||
STATfile.close();
|
||||
}
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_Heis_DSF.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 13 && argc != 14) { // Print out instructions
|
||||
//if (strcmp(argv[1],"help") == 0) { // Output some instructions
|
||||
cout << "Usage of Smoothen_Heis_DSF executable: " << endl << endl;
|
||||
cout << "Provide arguments using one of the following options:" << endl << endl;
|
||||
cout << "1) (for general momenta) whichDSF Delta N M iKmin iKmax DiK kBT ommin ommax Nom gwidth" << endl << endl;
|
||||
cout << "2) (for fixed momentum) whichDSF Delta N M iKneeded ommin ommax Nom gwidth" << endl << endl;
|
||||
//else JSCerror("Incomprehensible arguments in Smoothen_Heis_DSF executable.");
|
||||
}
|
||||
|
||||
else if (argc == 13) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
int DiK = atoi(argv[7]);
|
||||
DP kBT = atof(argv[8]);
|
||||
DP ommin = atof(argv[9]);
|
||||
DP ommax = atof(argv[10]);
|
||||
int Nom = atoi(argv[11]);
|
||||
DP gwidth = atof(argv[12]);
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, Delta, N, M, iKmin, iKmax, kBT, 0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI;
|
||||
DP denom_sum_K = 1.0/N;
|
||||
|
||||
Write_K_File (N, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
|
||||
DP sumcheck;
|
||||
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, gwidth, normalization, denom_sum_K);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
else if (argc == 10) { // fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKneeded = atoi(argv[5]);
|
||||
DP ommin = atof(argv[6]);
|
||||
DP ommax = atof(argv[7]);
|
||||
int Nom = atoi(argv[8]);
|
||||
DP gwidth = atof(argv[9]);
|
||||
|
||||
bool fixed_iK = true;
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, Delta, N, M, fixed_iK, iKneeded, 0.0, 0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI;
|
||||
int iKmin = iKneeded;
|
||||
int iKmax = iKneeded;
|
||||
|
||||
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
//else JSCerror("Wrong number of arguments to Smoothen_Heis_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_LiebLin_DSF.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 13) { // Print out instructions
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
|
||||
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
|
||||
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
|
||||
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
|
||||
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Smoothen_LiebLin_DSF d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 13) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int DiK = atoi(argv[8]);
|
||||
DP ommin = atof(argv[9]);
|
||||
DP ommax = atof(argv[10]);
|
||||
int Nom = atoi(argv[11]);
|
||||
DP width = atof(argv[12]);
|
||||
|
||||
stringstream filenameprefix;
|
||||
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
DP denom_sum_K = L;
|
||||
|
||||
Write_K_File (L, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
|
||||
// We use the scaled width function as default:
|
||||
|
||||
DP sumcheck;
|
||||
//if (kBT < 0.1)
|
||||
//sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
|
||||
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
|
||||
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
|
||||
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
|
||||
}
|
||||
|
||||
/*
|
||||
else if (argc == 11) { // fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iK_UL = atoi(argv[5]);
|
||||
int iKneeded = atoi(argv[6]);
|
||||
DP ommin = atof(argv[7]);
|
||||
DP ommax = atof(argv[8]);
|
||||
int Nom = atoi(argv[9]);
|
||||
DP gwidth = atof(argv[10]);
|
||||
|
||||
//bool fixed_iK = true;
|
||||
//LiebLin_Bethe_State GroundState (c_int, L, N, iK_UL, 0LL);
|
||||
stringstream filenameprefix;
|
||||
//Data_File_Name (filenameprefix, whichDSF, fixed_iK, iKneeded, GroundState, GroundState);
|
||||
//Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 0.0);
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, iKneeded, iKneeded, 0.0);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
int iKmin = iKneeded;
|
||||
int iKmax = iKneeded;
|
||||
|
||||
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
//else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_LiebLin_DSF_GeneralState.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 13) { // Print out instructions
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
|
||||
//cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
|
||||
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
|
||||
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
|
||||
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
|
||||
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Smoothen_LiebLin_DSF d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 13) { // !fixed_iK
|
||||
int n = 1;
|
||||
char whichDSF = *argv[n++];
|
||||
DP c_int = atof(argv[n++]);
|
||||
DP L = atof(argv[n++]);
|
||||
int N = atoi(argv[n++]);
|
||||
char* Ix2filenameprefix = argv[n++];
|
||||
int iKmin = atoi(argv[n++]);
|
||||
int iKmax = atoi(argv[n++]);
|
||||
//DP kBT = atof(argv[7]);
|
||||
DP kBT = 0.0;
|
||||
int DiK = atoi(argv[n++]);
|
||||
DP ommin = atof(argv[n++]);
|
||||
DP ommax = atof(argv[n++]);
|
||||
int Nom = atoi(argv[n++]);
|
||||
DP width = atof(argv[n++]);
|
||||
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
|
||||
stringstream filenameprefix;
|
||||
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
|
||||
//Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, defaultScanStatename);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
DP denom_sum_K = L;
|
||||
|
||||
Write_K_File (L, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
|
||||
// We use the scaled width function as default:
|
||||
|
||||
DP sumcheck;
|
||||
//if (kBT < 0.1)
|
||||
//sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
|
||||
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
|
||||
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
|
||||
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
|
||||
}
|
||||
|
||||
/*
|
||||
else if (argc == 11) { // fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iK_UL = atoi(argv[5]);
|
||||
int iKneeded = atoi(argv[6]);
|
||||
DP ommin = atof(argv[7]);
|
||||
DP ommax = atof(argv[8]);
|
||||
int Nom = atoi(argv[9]);
|
||||
DP gwidth = atof(argv[10]);
|
||||
|
||||
//bool fixed_iK = true;
|
||||
//LiebLin_Bethe_State GroundState (c_int, L, N, iK_UL, 0LL);
|
||||
stringstream filenameprefix;
|
||||
//Data_File_Name (filenameprefix, whichDSF, fixed_iK, iKneeded, GroundState, GroundState);
|
||||
//Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 0.0);
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, iKneeded, iKneeded, 0.0);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
int iKmin = iKneeded;
|
||||
int iKmax = iKneeded;
|
||||
|
||||
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
//else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_LiebLin_DSF_MosesState.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 15) { // Print out instructions
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Smoothen_LiebLin_DSF_MosesState executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
|
||||
//cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
|
||||
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
|
||||
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
|
||||
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
|
||||
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Smoothen_LiebLin_DSF_MosesState d 1.0 100.0 100 50 -30 40 0 200 1 0.0 10.0 500 2.0" << endl << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 15) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int Nl = atoi(argv[5]);
|
||||
//int Nr = N - Nl;
|
||||
int DIl = atoi(argv[6]);
|
||||
int DIr = atoi(argv[7]);
|
||||
int iKmin = atoi(argv[8]);
|
||||
int iKmax = atoi(argv[9]);
|
||||
//DP kBT = atof(argv[10]);
|
||||
DP kBT = 0.0;
|
||||
int DiK = atoi(argv[10]);
|
||||
DP ommin = atof(argv[11]);
|
||||
DP ommax = atof(argv[12]);
|
||||
int Nom = atoi(argv[13]);
|
||||
DP width = atof(argv[14]);
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
stringstream filenameprefix;
|
||||
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, defaultScanStatename);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
DP denom_sum_K = L;
|
||||
|
||||
Write_K_File (L, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
|
||||
// We use the scaled width function as default:
|
||||
|
||||
DP sumcheck;
|
||||
//if (kBT < 0.1)
|
||||
//sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
|
||||
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
|
||||
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
|
||||
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
|
||||
}
|
||||
|
||||
//else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_LiebLin_DSF_Scaled.cc
|
||||
|
||||
Purpose: produces .dsfs and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 13) { // Print out instructions
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Smoothen_LiebLin_DSF_Scaled executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
|
||||
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
|
||||
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
|
||||
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
|
||||
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Smoothen_LiebLin_DSF d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 13) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int DiK = atoi(argv[8]);
|
||||
DP ommin = atof(argv[9]);
|
||||
DP ommax = atof(argv[10]);
|
||||
int Nom = atoi(argv[11]);
|
||||
DP width = atof(argv[12]);
|
||||
|
||||
stringstream filenameprefix;
|
||||
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
//DP denom_sum_K = L;
|
||||
|
||||
Write_K_File (L, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
|
||||
// We use the scaled width function as default:
|
||||
|
||||
DP sumcheck;
|
||||
//if (kBT < 0.1)
|
||||
sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
|
||||
//sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
|
||||
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
|
||||
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
|
||||
}
|
||||
|
||||
//else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_LiebLin_DSF_over_Ensemble.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from an ensemble of .raw files
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 13) { // Print out instructions
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Smoothen_LiebLin_DSF_over_Ensemble executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
//cout << "int nstates \t\t\t Number of states considered in the ensemble" << endl;
|
||||
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
|
||||
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
|
||||
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
|
||||
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
|
||||
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Smoothen_LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 13) {
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
//int nstates_req = atoi(argv[8]);
|
||||
int DiK = atoi(argv[8]);
|
||||
DP ommin = atof(argv[9]);
|
||||
DP ommax = atof(argv[10]);
|
||||
int Nom = atoi(argv[11]);
|
||||
DP width = atof(argv[12]);
|
||||
|
||||
stringstream filenameprefix;
|
||||
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
DP denom_sum_K = L;
|
||||
|
||||
Write_K_File (L, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
|
||||
// Read the weights from the ensembles file:
|
||||
LiebLin_Diagonal_State_Ensemble ensemble;
|
||||
|
||||
stringstream ensfilestrstream;
|
||||
//ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
|
||||
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
|
||||
string ensfilestr = ensfilestrstream.str();
|
||||
const char* ensfile_Cstr = ensfilestr.c_str();
|
||||
|
||||
ensemble.Load(c_int, L, N, ensfile_Cstr);
|
||||
|
||||
// Define the raw file names
|
||||
Vect<string> rawfilename(ensemble.nstates);
|
||||
|
||||
for (int ns = 0; ns < ensemble.nstates; ++ns) {
|
||||
// Define the raw input file name:
|
||||
stringstream filenameprefix;
|
||||
//Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, kBT, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
|
||||
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
|
||||
string prefix = filenameprefix.str();
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
//RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
rawfilename[ns] = RAW_stringstream.str();
|
||||
}
|
||||
|
||||
Smoothen_RAW_into_SF (prefix, rawfilename, ensemble.weight, iKmin, iKmax, DiK,
|
||||
ommin, ommax, Nom, width, normalization, denom_sum_K);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_ODSLF_DSF.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 10 && argc != 11) { // Print out instructions
|
||||
//if (strcmp(argv[1],"help") == 0) { // Output some instructions
|
||||
cout << "Usage of Smoothen_ODSLF_DSF executable: " << endl << endl;
|
||||
cout << "Provide arguments using one of the following options:" << endl << endl;
|
||||
cout << "1) (for general momenta) whichDSF Delta N M iKmin iKmax ommin ommax Nom gwidth" << endl << endl;
|
||||
cout << "2) (for fixed momentum) whichDSF Delta N M iKneeded ommin ommax Nom gwidth" << endl << endl;
|
||||
//else JSCerror("Incomprehensible arguments in Smoothen_ODSLF_DSF executable.");
|
||||
}
|
||||
|
||||
else if (argc == 11) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP ommin = atof(argv[7]);
|
||||
DP ommax = atof(argv[8]);
|
||||
int Nom = atoi(argv[9]);
|
||||
DP gwidth = atof(argv[10]);
|
||||
|
||||
stringstream filenameprefix;
|
||||
ODSLF_Data_File_Name (filenameprefix, whichDSF, Delta, N, M, iKmin, iKmax, 0.0, 0);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI;
|
||||
|
||||
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
|
||||
|
||||
Write_K_File (N, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 10) { // fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKneeded = atoi(argv[5]);
|
||||
DP ommin = atof(argv[6]);
|
||||
DP ommax = atof(argv[7]);
|
||||
int Nom = atoi(argv[8]);
|
||||
DP gwidth = atof(argv[9]);
|
||||
|
||||
bool fixed_iK = true;
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, Delta, N, M, fixed_iK, iKneeded, 0.0, 0);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI;
|
||||
int iKmin = iKneeded;
|
||||
int iKmax = iKneeded;
|
||||
|
||||
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
|
||||
}
|
||||
|
||||
else JSCerror("Wrong number of arguments to Smoothen_Heis_DSF executable.");
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: ABACUS++G_2_testing.cc
|
||||
|
||||
Purpose: testing of ABACUS++2
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main( int argc, char* argv[])
|
||||
{
|
||||
if (!(argc == 3 || argc == 5)) { // provide some info
|
||||
cout << endl << "This code computes the (1/N) (-1)^j S^z_j on-site staggered magnetization for XXZ_gpd in zero field." << endl;
|
||||
cout << "First option: provide two arguments: anisotropy Delta (> 1) and system size N (even)." << endl;
|
||||
cout << "Second option: provide five arguments: system size N (even), Delta min, Delta max, NDelta." << endl;
|
||||
cout << "The output is Delta, N, stag mag, energy gap." << endl;
|
||||
JSCerror("");
|
||||
}
|
||||
else if (argc == 3) {
|
||||
DP Delta = atof(argv[1]);
|
||||
if (Delta <= 1.0) JSCerror("Provide Delta > 1.");
|
||||
int N = atoi(argv[2]);
|
||||
if (N % 2) JSCerror("Provide an even Delta.");
|
||||
int M = N/2;
|
||||
|
||||
// Define the chain: J, Delta, h, Nsites
|
||||
Heis_Chain chain(1.0, Delta, 0.0, N);
|
||||
|
||||
Heis_Base gbase(chain, M);
|
||||
|
||||
XXZ_gpd_Bethe_State gstate(chain, gbase);
|
||||
gstate.Compute_All(true);
|
||||
|
||||
XXZ_gpd_Bethe_State estate(chain, gbase);
|
||||
estate.Ix2[0][0] = M+1; // umklapp excitation
|
||||
estate.Compute_All(true);
|
||||
|
||||
stringstream basestrstream;
|
||||
basestrstream << M-2 << "x1";
|
||||
string basestr = basestrstream.str();
|
||||
Heis_Base basegap(chain, basestr);
|
||||
XXZ_gpd_Bethe_State estategap(chain, basegap);
|
||||
estategap.Compute_All(true);
|
||||
|
||||
if (!gstate.conv) JSCerror("Ground state did not converge.");
|
||||
if (!estate.conv) JSCerror("Umklapp state did not converge.");
|
||||
if (!estategap.conv) JSCerror("Gap state did not converge.");
|
||||
|
||||
cout << Delta << "\t" << N << "\t" << setprecision(12) << exp(real(ln_Sz_ME (gstate, estate)))/sqrt(N) << "\t" << estategap.E - gstate.E << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 5) { // Do a scan in Delta
|
||||
|
||||
int N = atoi(argv[1]);
|
||||
if (N % 2) JSCerror("Provide an even Delta.");
|
||||
int M = N/2;
|
||||
|
||||
DP Deltamin = atof(argv[2]);
|
||||
if (Deltamin <= 1.0) JSCerror("Provide Deltamin > 1.");
|
||||
|
||||
DP Deltamax = atof(argv[3]);
|
||||
if (Deltamin <= 1.0) JSCerror("Provide Deltamax > Deltamin.");
|
||||
|
||||
int NDelta = atoi(argv[4]);
|
||||
|
||||
for (int iDelta = 0; iDelta <= NDelta; ++iDelta) {
|
||||
|
||||
DP Delta = (Deltamin * (NDelta -iDelta) + Deltamax * iDelta)/NDelta;
|
||||
|
||||
// Define the chain: J, Delta, h, Nsites
|
||||
Heis_Chain chain(1.0, Delta, 0.0, N);
|
||||
|
||||
Heis_Base gbase(chain, M);
|
||||
|
||||
XXZ_gpd_Bethe_State gstate(chain, gbase);
|
||||
gstate.Compute_All(true);
|
||||
|
||||
XXZ_gpd_Bethe_State estate(chain, gbase);
|
||||
estate.Ix2[0][0] = M+1; // umklapp excitation
|
||||
estate.Compute_All(true);
|
||||
|
||||
stringstream basestrstream;
|
||||
basestrstream << M-2 << "x1";
|
||||
string basestr = basestrstream.str();
|
||||
Heis_Base basegap(chain, basestr);
|
||||
XXZ_gpd_Bethe_State estategap(chain, basegap);
|
||||
estategap.Compute_All(true);
|
||||
|
||||
if (!gstate.conv) JSCerror("Ground state did not converge.");
|
||||
if (!estate.conv) JSCerror("Umklapp state did not converge.");
|
||||
if (!estategap.conv) JSCerror("Gap state did not converge.");
|
||||
|
||||
cout << Delta << "\t" << N << "\t" << setprecision(12) << exp(real(ln_Sz_ME (gstate, estate)))/sqrt(N) << "\t" << estategap.E - gstate.E << endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c) 2007.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: mrqmin.cc
|
||||
|
||||
Purpose: Nonlinear fitting
|
||||
|
||||
Last modified: 14/08/07
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
void covsrt (SQMat_DP& covar, Vect<bool>& ia, const int mfit)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
int ma = ia.size();
|
||||
|
||||
for (i = mfit; i < ma; i++)
|
||||
for (j = 0; j < i+1; j++) covar[i][j] = covar[j][i] = 0.0;
|
||||
k = mfit - 1;
|
||||
for (j = ma - 1; j >= 0; j--) {
|
||||
if (ia[j]) {
|
||||
for (i = 0; i < ma; i++) SWAP(covar[i][k], covar[i][j]);
|
||||
for (i = 0; i < ma; i++) SWAP(covar[k][i], covar[j][i]);
|
||||
k--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c) 2006.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: lin_reg.cc
|
||||
|
||||
Purpose: Linear regression
|
||||
|
||||
Last modified: 11/05/07
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
void lin_reg (Vect_DP x, Vect_DP y, Vect_DP sigma, DP& a, DP& b, DP& chisq)
|
||||
{
|
||||
// Performs simple linear regression on data
|
||||
|
||||
int Npts = x.size();
|
||||
|
||||
DP S = 0.0;
|
||||
DP Sx = 0.0;
|
||||
DP Sy = 0.0;
|
||||
DP Stt = 0.0;
|
||||
Vect_DP t(0.0, Npts);
|
||||
|
||||
for (int i = 0; i < Npts; ++i) {
|
||||
S += 1.0/(sigma[i] * sigma[i]);
|
||||
Sx += x[i]/(sigma[i] * sigma[i]);
|
||||
Sy += y[i]/(sigma[i] * sigma[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < Npts; ++i) {
|
||||
t[i] = (x[i] - Sx/S)/sigma[i];
|
||||
Stt += t[i] * t[i];
|
||||
}
|
||||
|
||||
a = 0.0;
|
||||
b = 0.0;
|
||||
for (int i = 0; i < Npts; ++i) {
|
||||
b += t[i] * y[i]/sigma[i];
|
||||
}
|
||||
b /= Stt;
|
||||
a = (Sy - Sx * b)/S;
|
||||
|
||||
chisq = 0.0;
|
||||
for (int i = 0; i < Npts; ++i) {
|
||||
chisq += (y[i] - a - b * x[i]) * (y[i] - a - b * x[i]) / (sigma[i] * sigma[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void lin_reg (Vect_DP x, Vect_DP y, DP& a, DP& b, DP& chisq)
|
||||
{
|
||||
// Assumes all sigma == 1
|
||||
|
||||
Vect_DP sigma(1.0, x.size());
|
||||
|
||||
lin_reg (x, y, sigma, a, b, chisq);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c) 2007.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: mrqmin.cc
|
||||
|
||||
Purpose: Nonlinear fitting
|
||||
|
||||
Last modified: 14/08/07
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
void mrqmin (Vect_DP& x, Vect_DP& y, Vect_DP& sig, Vect_DP& a,
|
||||
Vect<bool>& ia, SQMat_DP& covar, SQMat_DP& alpha, DP& chisq,
|
||||
void funcs(const DP, Vect_DP&, DP&, Vect_DP&), DP& alambda)
|
||||
{
|
||||
// Levenberg-Marquardt method. See NRC++ p.691.
|
||||
|
||||
static int mfit;
|
||||
static DP ochisq;
|
||||
int j, k, l;
|
||||
|
||||
int ma = a.size();
|
||||
static SQMat_DP oneda (ma);
|
||||
static Vect_DP atry(ma);
|
||||
static Vect_DP beta(ma);
|
||||
static Vect_DP da(ma);
|
||||
|
||||
if (alambda < 0.0) {
|
||||
mfit = 0;
|
||||
for (j = 0; j < ma; j++)
|
||||
if (ia[j]) mfit++;
|
||||
alambda = 0.001;
|
||||
mrqcof (x, y, sig, a, ia, alpha, beta, chisq, funcs);
|
||||
ochisq = chisq;
|
||||
for (j = 0; j < ma; j++) atry[j] = a[j];
|
||||
}
|
||||
|
||||
SQMat_DP temp (mfit);
|
||||
|
||||
for (j = 0; j < mfit; j++) {
|
||||
for (k = 0; k < mfit; k++) covar[j][k] = alpha[j][k];
|
||||
covar[j][j] = alpha[j][j] * (1.0 + alambda);
|
||||
for (k = 0; k < mfit; k++) temp[j][k] = covar[j][k];
|
||||
oneda[j][0] = beta[j];
|
||||
}
|
||||
|
||||
gaussj (temp, oneda);
|
||||
for (j = 0; j < mfit; j++) {
|
||||
for (k = 0; k < mfit; k++) covar[j][k] = temp[j][k];
|
||||
da[j] = oneda[j][0];
|
||||
}
|
||||
|
||||
if (alambda == 0.0) {
|
||||
covsrt (covar, ia, mfit);
|
||||
covsrt (alpha, ia, mfit);
|
||||
return;
|
||||
}
|
||||
|
||||
for (j = 0, l = 0; l < ma; l++)
|
||||
if (ia[l]) atry[l] = a[l] + da[j++];
|
||||
|
||||
mrqcof (x, y, sig, atry, ia, covar, da, chisq, funcs);
|
||||
|
||||
if (chisq < ochisq) {
|
||||
alambda *= 0.1;
|
||||
ochisq = chisq;
|
||||
for (j = 0; j < mfit; j++) {
|
||||
for (k = 0; k < mfit; k++) alpha[j][k] = covar[j][k];
|
||||
beta[j] = da[j];
|
||||
}
|
||||
for (l = 0; l < ma; l++) a[l] = atry[l];
|
||||
} else {
|
||||
alambda *= 10.0;
|
||||
chisq = ochisq;
|
||||
}
|
||||
}
|
||||
|
||||
void mrqcof (Vect_DP& x, Vect_DP& y, Vect_DP& sig, Vect_DP& a,
|
||||
Vect<bool>& ia, SQMat_DP& alpha, Vect_DP& beta, DP& chisq,
|
||||
void funcs (const DP, Vect_DP&, DP&, Vect_DP&))
|
||||
{
|
||||
int i, j, k, l, m, mfit = 0;
|
||||
DP ymod, wt, sig2i, dy;
|
||||
|
||||
int ndata = x.size();
|
||||
int ma = a.size();
|
||||
|
||||
Vect_DP dyda (ma);
|
||||
|
||||
for (j = 0; j < ma; j++)
|
||||
if (ia[j]) mfit++;
|
||||
for (j = 0; j < mfit; j++) {
|
||||
for (k = 0; k <= j; k++) alpha[j][k] = 0.0;
|
||||
beta[j] = 0.0;
|
||||
}
|
||||
|
||||
chisq = 0.0;
|
||||
for (i = 0; i < ndata; i++) {
|
||||
funcs (x[i], a, ymod, dyda);
|
||||
sig2i = 1.0/(sig[i] * sig[i]);
|
||||
dy = y[i] - ymod;
|
||||
for (j = 0, l = 0; l < ma; l++) {
|
||||
if (ia[l]) {
|
||||
wt = dyda[l] * sig2i;
|
||||
for (k = 0, m = 0; m < l+1; m++)
|
||||
if (ia[m]) alpha[j][k++] += wt * dyda[m];
|
||||
beta[j++] += dy * wt;
|
||||
}
|
||||
}
|
||||
chisq += dy * dy * sig2i;
|
||||
}
|
||||
for (j = 1; j < mfit; j++)
|
||||
for (k = 0; k < j; k++) alpha[k][j] = alpha[j][k];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include "JSC.h"
|
||||
using namespace std;
|
||||
|
||||
void JSC::polint(Vect_DP& xa, Vect_DP& ya, const DP x, DP& y, DP& dy)
|
||||
{
|
||||
// Polynomial interpolation/extrapolation, NR page 113.
|
||||
|
||||
int i, m, ns=0;
|
||||
DP den, dif, dift, ho, hp, w;
|
||||
|
||||
int n = xa.size();
|
||||
Vect_DP c(n), d(n);
|
||||
dif = fabs(x-xa[0]);
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((dift = fabs(x-xa[i])) < dif) {
|
||||
ns = i;
|
||||
dif = dift;
|
||||
}
|
||||
c[i] = ya[i];
|
||||
d[i] = ya[i];
|
||||
}
|
||||
y = ya[ns--];
|
||||
for (m = 1; m < n; m++) {
|
||||
for (i = 0; i < n-m; i++) {
|
||||
ho = xa[i] - x;
|
||||
hp = xa[i+m] - x;
|
||||
w = c[i+1] - d[i];
|
||||
if ((den = ho-hp) == 0.0) JSCerror("Error in routine polint.");
|
||||
den = w/den;
|
||||
d[i] = hp * den;
|
||||
c[i] = ho * den;
|
||||
}
|
||||
y += (dy = (2 * (ns + 1) < (n-m) ? c[ns + 1] : d[ns--]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "JSC.h"
|
||||
using namespace std;
|
||||
|
||||
void JSC::polint(Vect_CX& xa, Vect_CX& ya, const complex<DP> x, complex<DP>& y, complex<DP>& dy)
|
||||
{
|
||||
// Polynomial interpolation/extrapolation, NR page 113.
|
||||
|
||||
int i, m, ns=0;
|
||||
DP dif, dift;
|
||||
complex<DP> den, ho, hp, w;
|
||||
|
||||
int n = xa.size();
|
||||
Vect_CX c(n), d(n);
|
||||
dif = abs(x-xa[0]);
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((dift = abs(x-xa[i])) < dif) {
|
||||
ns = i;
|
||||
dif = dift;
|
||||
}
|
||||
c[i] = ya[i];
|
||||
d[i] = ya[i];
|
||||
}
|
||||
y = ya[ns--];
|
||||
for (m = 1; m < n; m++) {
|
||||
for (i = 0; i < n-m; i++) {
|
||||
ho = xa[i] - x;
|
||||
hp = xa[i+m] - x;
|
||||
w = c[i+1] - d[i];
|
||||
if ((den = ho-hp) == 0.0) JSCerror("Error in routine polint_cx.");
|
||||
den = w/den;
|
||||
d[i] = hp * den;
|
||||
c[i] = ho * den;
|
||||
}
|
||||
y += (dy = (2 * (ns + 1) < (n-m) ? c[ns + 1] : d[ns--]));
|
||||
}
|
||||
}
|
||||
+1717
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,142 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/Heis_Chem_Pot.cc
|
||||
|
||||
Purpose: calculates the chemical potential.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
DP Ezero (DP Delta, int N, int M)
|
||||
{
|
||||
// Returns the energy of the ground state with M down spins
|
||||
|
||||
if (M < 0 || M > N/2) JSCerror("M out of bounds in Ezero.");
|
||||
|
||||
DP E = -1.0; // sentinel value
|
||||
|
||||
if (M == 0) E = N * Delta/4.0;
|
||||
|
||||
else {
|
||||
|
||||
Heis_Chain BD1(1.0, Delta, 0.0, N);
|
||||
|
||||
Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
|
||||
|
||||
Nrapidities_groundstate[0] = M;
|
||||
|
||||
Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
|
||||
|
||||
if ((Delta > 0.0) && (Delta < 1.0)) {
|
||||
XXZ_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else if (Delta == 1.0) {
|
||||
XXX_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else if (Delta > 1.0) {
|
||||
XXZ_gpd_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else JSCerror("Anisotropy out of bounds in Ezero.");
|
||||
}
|
||||
|
||||
return(E);
|
||||
}
|
||||
|
||||
DP H_vs_M (DP Delta, int N, int M)
|
||||
{
|
||||
// Assumes dE/dM = 0 = dE_0/dM + h, with dE_0/dM = E_0(M) - E_0 (M - 1)
|
||||
|
||||
DP H = 0.0;
|
||||
|
||||
if (2*M == N) H = 0.0;
|
||||
|
||||
else if (Delta <= 1.0) H = Ezero (Delta, N, M - 1) - Ezero (Delta, N, M);
|
||||
|
||||
return(H);
|
||||
}
|
||||
|
||||
DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref)
|
||||
{
|
||||
if (M < 0 || M > N/2 - 1) {
|
||||
cout << "M = " << M << endl;
|
||||
JSCerror("M out of bounds in HZmin.");
|
||||
}
|
||||
|
||||
if (Ezero_ref[M] == -1.0) Ezero_ref[M] = Ezero(Delta, N, M);
|
||||
if (Ezero_ref[M + 1] == -1.0) Ezero_ref[M + 1] = Ezero(Delta, N, M + 1);
|
||||
|
||||
return(Ezero_ref[M] - Ezero_ref[M + 1]);
|
||||
}
|
||||
|
||||
int M_vs_H (DP Delta, int N, DP HZ)
|
||||
{
|
||||
// Returns the value of M for given field HZ
|
||||
|
||||
if (HZ < 0.0) JSCerror("Please use a positive field in M_vs_H.");
|
||||
|
||||
else if (HZ == 0.0) return(N/2);
|
||||
|
||||
// Here, -1.0 is a sentinel value.
|
||||
Vect_DP Ezero(-1.0, N/2 + 1); // contains the GSE[M].
|
||||
|
||||
// We look for M s.t. HZmin[M] < HZ <= HZmin[M + 1]
|
||||
|
||||
int M_actual = N/4; // start somewhere in middle
|
||||
int M_step = N/8 - 1; // step
|
||||
DP HZmin_actual = 0.0;
|
||||
DP HZmax_actual = 0.0;
|
||||
bool M_found = false;
|
||||
|
||||
if (HZ >= 1.0 + Delta) M_actual = 0; // saturation
|
||||
|
||||
else {
|
||||
|
||||
HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
|
||||
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
|
||||
|
||||
while (!M_found) {
|
||||
|
||||
if (HZmin_actual > HZ) M_actual += M_step;
|
||||
else if (HZmax_actual <= HZ) M_actual -= M_step;
|
||||
|
||||
M_step = (M_step + 1)/2;
|
||||
|
||||
HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
|
||||
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
|
||||
|
||||
M_found = (HZmin_actual < HZ && HZ <= HZmax_actual);
|
||||
|
||||
//cout << "M_actual = " << M_actual << "\tM_step = " << M_step
|
||||
// << "\tHZmin_actual = " << HZmin_actual << "\tHZmax_actual = " << HZmax_actual << "\tHZ = " << HZ << "\t" << M_found << endl;
|
||||
}
|
||||
}
|
||||
//cout << "M found = " << M_actual << "\tHZmax = " << Ezero[M_actual] - Ezero[M_actual + 1] << "\tHZmin = " << Ezero[M_actual - 1] - Ezero[M_actual] << endl;
|
||||
|
||||
return(M_actual);
|
||||
}
|
||||
|
||||
DP Chemical_Potential (const Heis_Bethe_State& AveragingState)
|
||||
{
|
||||
return(-H_vs_M (AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown)); // - sign since E_{M+1} - E_M = -H
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,376 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/Heis_Matrix_Element_Contrib.cc
|
||||
|
||||
Purpose: handles the generic call for a matrix element.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXZ_Bethe_State& LeftState,
|
||||
//XXZ_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState,
|
||||
// XXZ_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState,
|
||||
XXZ_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
|
||||
{
|
||||
// This function prints the matrix information to the fstream,
|
||||
// and returns a weighed `data_value' to be multiplied by sumrule_factor,
|
||||
// to determine if scanning along this thread should be continued.
|
||||
|
||||
// Identify which matrix element is needed from the number of particles in Left and Right states:
|
||||
|
||||
bool fixed_iK = (iKmin == iKmax);
|
||||
|
||||
DP ME = 0.0;
|
||||
if (!(LeftState.conv && RightState.conv)) ME = 0.0;
|
||||
|
||||
else if (whichDSF == 'Z')
|
||||
ME = LeftState.E - RightState.E;
|
||||
else if (whichDSF == 'm')
|
||||
ME = exp(real(ln_Smin_ME (RightState, LeftState)));
|
||||
else if (whichDSF == 'z') {
|
||||
if (LeftState.label == RightState.label)
|
||||
//MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
|
||||
ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
|
||||
else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
|
||||
}
|
||||
else if (whichDSF == 'p')
|
||||
ME = exp(real(ln_Smin_ME (LeftState, RightState)));
|
||||
else JSCerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
|
||||
|
||||
if (is_nan(ME)) ME = 0.0;
|
||||
|
||||
//if (LeftState.dev > 1.0e-16 || RightState.dev > 1.0e-16) ME = 0.0; // kill deviated contributions
|
||||
|
||||
// Do the momentum business:
|
||||
int iKout = LeftState.iK - RightState.iK;
|
||||
while(iKout < 0) iKout += RightState.chain.Nsites;
|
||||
while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
|
||||
|
||||
// Print information to fstream:
|
||||
if (iKout >= iKmin && iKout <= iKmax) {
|
||||
if (whichDSF == 'Z') {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
else {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
} // if iKmin <= iKout <= iKmax
|
||||
|
||||
// Calculate and return the data_value:
|
||||
DP data_value = ME * ME;
|
||||
//DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
|
||||
|
||||
if (whichDSF == 'Z') // use 1/(1 + omega)
|
||||
data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
else if (fixed_iK) // data value is MEsq * omega:
|
||||
data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
|
||||
return(data_value);
|
||||
}
|
||||
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXX_Bethe_State& LeftState,
|
||||
//XXX_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState,
|
||||
//XXX_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState,
|
||||
XXX_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
|
||||
{
|
||||
// This function prints the matrix element information to the fstream,
|
||||
// and returns a weighed `data_value' to be multiplied by sumrule_factor,
|
||||
// to determine if scanning along this thread should be continued.
|
||||
|
||||
// Identify which matrix element is needed from the number of particles in Left and Right states:
|
||||
|
||||
bool fixed_iK = (iKmin == iKmax);
|
||||
|
||||
DP ME = 0.0;
|
||||
complex<DP> ME_CX = 0.0;
|
||||
|
||||
int nrinfrap = 0; // for energy shift from chemical potential
|
||||
|
||||
if (!(LeftState.conv && RightState.conv)) { ME = 0.0; ME_CX = 0.0;}
|
||||
|
||||
else if (whichDSF == 'Z')
|
||||
ME = LeftState.E - RightState.E;
|
||||
else if (whichDSF == 'm')
|
||||
ME = exp(real(ln_Smin_ME (RightState, LeftState)));
|
||||
else if (whichDSF == 'z') {
|
||||
// Recognize the presence of an infinite rapidity:
|
||||
if (LeftState.base.Mdown == RightState.base.Mdown - 1) { // infinite rapidity present, use rescaled S^- matrix element instead of S^z one:
|
||||
nrinfrap = 1;
|
||||
// Correction factor for MEsq: Smffsq to Szffsq = 1/(N - 2M + 2)
|
||||
ME = sqrt(1.0/(RightState.chain.Nsites - 2*RightState.base.Mdown + 2)) * exp(real(ln_Smin_ME (RightState, LeftState)));
|
||||
}
|
||||
else { // no infinite rapidity, use S^z matrix element:
|
||||
if (LeftState.label == RightState.label)
|
||||
//MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
|
||||
ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
|
||||
else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
|
||||
}
|
||||
}
|
||||
else if (whichDSF == 'p') {
|
||||
// Recognize the presence of two infinite rapidities:
|
||||
if (LeftState.base.Mdown == RightState.base.Mdown - 1) { // two infinite rapidities, use rescaled S^- matrix element instead of S^+
|
||||
nrinfrap = 2;
|
||||
// Correction factor for MEsq: Smffsq to Spffsq = 2/((N - 2M + 2) (N - 2M + 1))
|
||||
ME = sqrt(2.0/((RightState.chain.Nsites - 2*RightState.base.Mdown + 2.0) * (RightState.chain.Nsites - 2*RightState.base.Mdown + 1.0)))
|
||||
* exp(real(ln_Smin_ME (RightState, LeftState)));
|
||||
}
|
||||
else if (LeftState.base.Mdown == RightState.base.Mdown) { // one infinite rapidity, use rescaled S^z matrix element instead of S^+
|
||||
nrinfrap = 1;
|
||||
// Correction factor for MEsq: Szffsq to Spffsq = 4/(N - 2M)
|
||||
ME = sqrt(4.0/(RightState.chain.Nsites - 2* RightState.base.Mdown)) * exp(real(ln_Sz_ME (RightState, LeftState)));
|
||||
}
|
||||
else ME = exp(real(ln_Smin_ME (LeftState, RightState)));
|
||||
}
|
||||
else if (whichDSF == 'a') // S^z_j S^z_{j+1} operator
|
||||
ME = exp(real(ln_Szz_ME (LeftState, RightState)));
|
||||
else if (whichDSF == 'b') // S^z_j S^-_{j+1} + h.c. operator
|
||||
ME = exp(real(ln_Szm_p_Smz_ME (RightState, LeftState)));
|
||||
else if (whichDSF == 'c') // S^-_j S^-{j+1} operator
|
||||
ME = exp(real(ln_Smm_ME (RightState, LeftState)));
|
||||
else if (whichDSF == 'q') // Geometric quench
|
||||
//ME_CX = ln_Overlap (LeftState, RightState);
|
||||
ME_CX = ln_Overlap (RightState, LeftState);
|
||||
else JSCerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
|
||||
|
||||
if (is_nan(ME)) ME = 0.0;
|
||||
if (is_nan(norm(ME_CX))) ME_CX = -100.0;
|
||||
|
||||
//if (LeftState.dev > 1.0e-16 || RightState.dev > 1.0e-16) {
|
||||
//ME = 0.0; ME_CX = (0.0,0.0); // kill deviated contributions
|
||||
//}
|
||||
|
||||
// Do the momentum business:
|
||||
int iKout = LeftState.iK - RightState.iK;
|
||||
while(iKout < 0) iKout += RightState.chain.Nsites;
|
||||
while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
|
||||
|
||||
// Print information to fstream:
|
||||
if (iKout >= iKmin && iKout <= iKmax) {
|
||||
if (whichDSF == 'Z') {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
else if (whichDSF == 'q') {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
<< real(ME_CX) << "\t" << imag(ME_CX) - twoPI * int(imag(ME_CX)/twoPI + 1.0e-10) << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
|
||||
else {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
} // if iKmin <= iKout <= iKmax
|
||||
|
||||
// Calculate and return the data_value:
|
||||
DP data_value = ME * ME;
|
||||
//DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
|
||||
if (whichDSF == 'Z') // use 1/(1 + omega)
|
||||
data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
else if (whichDSF == 'q')
|
||||
data_value = exp(2.0 * real(ME_CX));
|
||||
else if (fixed_iK) // data value is MEsq * omega:
|
||||
data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
|
||||
return(data_value);
|
||||
}
|
||||
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXZ_gpd_Bethe_State& LeftState,
|
||||
//XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState,
|
||||
// XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState,
|
||||
XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
|
||||
{
|
||||
// This function prints the matrix element information to the fstream,
|
||||
// and returns a weighed `data_value' to be multiplied by sumrule_factor,
|
||||
// to determine if scanning along this thread should be continued.
|
||||
|
||||
/*
|
||||
cout << "\t" << LeftState.label << endl << "\t" << LeftState.Ix2 << endl;
|
||||
cout << "\t0: ";
|
||||
for (int i = 0; i < LeftState.base.Nrap[0]; ++i) cout << LeftState.lambda[0][i]*2.0/PI << "\t";
|
||||
cout << endl;
|
||||
cout << "\t1: ";
|
||||
for (int i = 0; i < LeftState.base.Nrap[1]; ++i) cout << LeftState.lambda[1][i]*2.0/PI << "\t";
|
||||
cout << endl;
|
||||
*/
|
||||
|
||||
bool fixed_iK = (iKmin == iKmax);
|
||||
|
||||
|
||||
// If any of the rapidities outside of fundamental interval -pi/2 < lambda <= pi/2, set matrix element to zero.
|
||||
bool rap_in_fundamental = true;
|
||||
int sum1 = 0;
|
||||
for (int j = 0; j < LeftState.chain.Nstrings; ++j) {
|
||||
//for (int alpha = 0; alpha < LeftState.base.Nrap[j]; ++alpha) {
|
||||
//if (LeftState.lambda[j][alpha] <= -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
|
||||
//if (LeftState.lambda[j][alpha] <= -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
|
||||
//rap_in_fundamental = false;
|
||||
//}
|
||||
|
||||
/*
|
||||
// TEST 2014 06 26: comment this out, replace by -\pi/2 \leq \lambda \leq \pi/2, see below
|
||||
if (LeftState.base.Nrap[j] > 0 && LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
|
||||
rap_in_fundamental = false;
|
||||
|
||||
sum1 = 0;
|
||||
for (int k = 0; k < LeftState.chain.Nstrings; ++k)
|
||||
sum1 += LeftState.base.Nrap[k] * (2 * JSC::min(LeftState.chain.Str_L[j], LeftState.chain.Str_L[k]) - ((j == k) ? 1 : 0));
|
||||
// This almost does it: only missing are the states with one on -PI/2 and one on PI/2
|
||||
if (LeftState.base.Nrap[j] >= 1
|
||||
&& (LeftState.Ix2[j][0] <= -(LeftState.chain.Nsites - sum1)
|
||||
|| (LeftState.Ix2[j][LeftState.base.Nrap[j] - 1] - LeftState.Ix2[j][0])
|
||||
> 2*(LeftState.chain.Nsites - sum1)))
|
||||
rap_in_fundamental = false;
|
||||
*/
|
||||
|
||||
// attempt 2014 06 26
|
||||
//for (int alpha = 0; alpha < LeftState.base.Nrap[j]; ++alpha) {
|
||||
//if (LeftState.lambda[j][alpha] < -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
|
||||
// rap_in_fundamental = false;
|
||||
//}
|
||||
/*
|
||||
if (LeftState.base.Nrap[j] > 0 &&
|
||||
((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
|
||||
|| LeftState.lambda[j][0] < -0.5*PI + 1.0e-10
|
||||
|| LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > 0.5*PI
|
||||
//|| LeftState.lambda[j][0] > 0.5*PI
|
||||
//((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI - 1.0e-10)
|
||||
//|| LeftState.lambda[j][0] < -0.5*PI + 1.0e-10
|
||||
//|| LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > 0.5*PI + 1.0e-10
|
||||
)) // include safety in limits
|
||||
rap_in_fundamental = false;
|
||||
*/
|
||||
/*
|
||||
if (LeftState.base.Nrap[j] > 0 &&
|
||||
((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
|
||||
//|| (LeftState.base.Nrap[j] == 1 && fabs(LeftState.lambda[j][0]) > 0.5*PI)
|
||||
))
|
||||
rap_in_fundamental = false;
|
||||
*/
|
||||
|
||||
// Logic: allow rapidities -PI/2 <= lambda <= PI/2 (including boundaries)
|
||||
if (LeftState.base.Nrap[j] > 0 &&
|
||||
(LeftState.lambda[j][0] < -PI/2 || LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > PI/2))
|
||||
rap_in_fundamental = false;
|
||||
if (RightState.base.Nrap[j] > 0 &&
|
||||
(RightState.lambda[j][0] < -PI/2 || RightState.lambda[j][RightState.base.Nrap[j] - 1] > PI/2))
|
||||
rap_in_fundamental = false;
|
||||
|
||||
// rapidities should also be ordered as the quantum numbers:
|
||||
for (int alpha = 1; alpha < LeftState.base.Nrap[j]; ++alpha)
|
||||
if (LeftState.lambda[j][alpha - 1] >= LeftState.lambda[j][alpha])
|
||||
rap_in_fundamental = false;
|
||||
for (int alpha = 1; alpha < RightState.base.Nrap[j]; ++alpha)
|
||||
if (RightState.lambda[j][alpha - 1] >= RightState.lambda[j][alpha])
|
||||
rap_in_fundamental = false;
|
||||
|
||||
} // for int j
|
||||
|
||||
|
||||
// Identify which matrix element is needed from the number of particles in Left and Right states:
|
||||
DP ME = 0.0;
|
||||
//if (!(LeftState.conv && RightState.conv)) ME = 0.0;
|
||||
if (!(LeftState.conv && RightState.conv && rap_in_fundamental)) ME = 0.0;
|
||||
|
||||
else if (whichDSF == 'Z')
|
||||
ME = LeftState.E - RightState.E;
|
||||
else if (whichDSF == 'm')
|
||||
ME = exp(real(ln_Smin_ME (RightState, LeftState)));
|
||||
else if (whichDSF == 'z') {
|
||||
if (LeftState.label == RightState.label)
|
||||
//MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
|
||||
ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
|
||||
else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
|
||||
}
|
||||
else if (whichDSF == 'p')
|
||||
ME = exp(real(ln_Smin_ME (LeftState, RightState)));
|
||||
else JSCerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
|
||||
|
||||
if (is_nan(ME)) ME = 0.0;
|
||||
|
||||
//if (LeftState.dev > 1.0e+2 || RightState.dev > 1.0e+2) ME = 0.0; // kill deviated contributions
|
||||
if (fabs(ME) > 1.0) ME = 0.0;
|
||||
|
||||
// Do the momentum business:
|
||||
int iKout = LeftState.iK - RightState.iK;
|
||||
while(iKout < 0) iKout += RightState.chain.Nsites;
|
||||
while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
|
||||
|
||||
// Print information to fstream:
|
||||
if (iKout >= iKmin && iKout <= iKmax) {
|
||||
if (whichDSF == 'Z') {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
else {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
|
||||
/*
|
||||
cout << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" << iKout << "\t" << ME << "\t" << setprecision(3) << LeftState.dev << "\t" << LeftState.label << "\t" << setprecision(16) << LeftState.lambda[0][0]/PI << "\t" << LeftState.Ix2[0][0] << "\t" << LeftState.lambda[0][LeftState.base.Nrap[0] - 1]/PI << "\t" << LeftState.Ix2[0][LeftState.base.Nrap[0] - 1];
|
||||
if (LeftState.base.Nrap[1] > 0) cout << "\t" << LeftState.lambda[1][0]/PI << "\t" << LeftState.Ix2[1][0];
|
||||
if (LeftState.lambda[0][0] < -0.5*PI + 1.0e-10 || LeftState.lambda[0][LeftState.base.Nrap[0] - 1] > 0.5*PI - 1.0e-10 || (LeftState.base.Nrap[1] > 0 && (LeftState.lambda[1][0] < -0.5*PI || LeftState.lambda[1][0] > 0.5*PI))) cout << "\t" << "*****";
|
||||
cout << endl;
|
||||
*/
|
||||
|
||||
}
|
||||
} // if iKmin <= iKout <= iKmax
|
||||
|
||||
// Calculate and return the data_value:
|
||||
DP data_value = ME * ME;
|
||||
//DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
|
||||
if (whichDSF == 'Z') // use 1/(1 + omega)
|
||||
data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
else if (fixed_iK) // data value is MEsq * omega:
|
||||
data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
|
||||
return(data_value);
|
||||
}
|
||||
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,255 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/Heis_Sumrules.cc
|
||||
|
||||
Purpose: defines sumrule factors for Heisenberg
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
DP X_avg (char xyorz, DP Delta, int N, int M)
|
||||
{
|
||||
// Calculates \sum_j < S_j^a S_{j+1}^a >, a = x, y or z.
|
||||
|
||||
DP eps_Delta = 0.00000001;
|
||||
|
||||
if (Delta < 1.0 && 1.0 - Delta < 1.0e-6) eps_Delta *= -1.0;
|
||||
|
||||
// Define the chain: J, Delta, h, Nsites
|
||||
Heis_Chain chain(1.0, Delta, 0.0, N);
|
||||
|
||||
// Define the base: chain, Mdown
|
||||
Heis_Base gbase(chain, M);
|
||||
|
||||
// Define the chain: J, Delta, h, Nsites
|
||||
Heis_Chain chain2(1.0, Delta + eps_Delta, 0.0, N);
|
||||
|
||||
// Define the base: chain, Mdown
|
||||
Heis_Base gbase2(chain2, M);
|
||||
|
||||
DP E0_Delta = 0.0;
|
||||
DP E0_Delta_eps = 0.0;
|
||||
|
||||
if (Delta > 0.0 && Delta < 1.0) {
|
||||
|
||||
// Define the ground state
|
||||
XXZ_Bethe_State gstate(chain, gbase);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate.Compute_All(true);
|
||||
|
||||
E0_Delta = gstate.E;
|
||||
|
||||
// Define the ground state
|
||||
XXZ_Bethe_State gstate2(chain2, gbase2);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate2.Compute_All(true);
|
||||
|
||||
E0_Delta_eps = gstate2.E;
|
||||
}
|
||||
|
||||
else if (Delta == 1.0) {
|
||||
// Define the ground state
|
||||
XXX_Bethe_State gstate(chain, gbase);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate.Compute_All(true);
|
||||
|
||||
E0_Delta = gstate.E;
|
||||
|
||||
// Define the ground state
|
||||
XXZ_gpd_Bethe_State gstate2(chain2, gbase2); // need XXZ_gpd here
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate2.Compute_All(true);
|
||||
|
||||
E0_Delta_eps = gstate2.E;
|
||||
}
|
||||
|
||||
else if (Delta > 1.0) {
|
||||
// Define the ground state
|
||||
XXZ_gpd_Bethe_State gstate(chain, gbase);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate.Compute_All(true);
|
||||
|
||||
E0_Delta = gstate.E;
|
||||
|
||||
// Define the ground state
|
||||
XXZ_gpd_Bethe_State gstate2(chain2, gbase2);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate2.Compute_All(true);
|
||||
|
||||
E0_Delta_eps = gstate2.E;
|
||||
}
|
||||
|
||||
else JSCerror("Wrong anisotropy in S1_sumrule_factor.");
|
||||
|
||||
DP answer = 0.0;
|
||||
//if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
|
||||
if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
|
||||
|
||||
// Careful for z ! Hamiltonian defined as S^z S^z - 1/4, so add back N/4:
|
||||
else if (xyorz == 'z') answer = (E0_Delta_eps - E0_Delta)/eps_Delta + 0.25 * N;
|
||||
|
||||
else JSCerror("option not implemented in X_avg.");
|
||||
|
||||
return(answer);
|
||||
}
|
||||
|
||||
DP S1_sumrule_factor (char mporz, DP Delta, int N, int M, DP Chem_Pot, int iK)
|
||||
{
|
||||
|
||||
DP X_x = X_avg ('x', Delta, N, M);
|
||||
DP X_z = X_avg ('z', Delta, N, M);
|
||||
|
||||
DP sumrule = 0.0;
|
||||
|
||||
if (mporz == 'm' || mporz == 'p') sumrule = - 4.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z + 0.5 * Chem_Pot * 0.5 *(N - 2*M))/N;
|
||||
//if (mporz == 'm' || mporz == 'p') sumrule = - 1.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * 2.0 * X_x + (Delta - cos((twoPI * iK)/N)) * (X_x + X_z))/N;
|
||||
|
||||
else if (mporz == 'z') sumrule = iK == 0 ? 1.0 : -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
|
||||
|
||||
else if (mporz == 'Z') sumrule = 1.0; // partition function
|
||||
else if (mporz == 'a') sumrule = 1.0;
|
||||
else if (mporz == 'b') sumrule = 1.0;
|
||||
else if (mporz == 'c') sumrule = 1.0;
|
||||
|
||||
else JSCerror("option not implemented in S1_sumrule_factor.");
|
||||
|
||||
//return(1.0/sumrule);
|
||||
return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N
|
||||
}
|
||||
|
||||
DP S1_sumrule_factor (char mporz, DP Delta, int N, int M, DP Chem_Pot, DP X_x, DP X_z, int iK)
|
||||
{
|
||||
|
||||
//DP X_x = X_avg ('x', Delta, N, M);
|
||||
//DP X_z = X_avg ('z', Delta, N, M);
|
||||
|
||||
DP sumrule = 0.0;
|
||||
|
||||
if (mporz == 'm' || mporz == 'p') sumrule = - 4.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z + 0.5 * Chem_Pot * 0.5 *(N - 2*M))/N;
|
||||
//if (mporz == 'm' || mporz == 'p') sumrule = - 1.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * 2.0 * X_x + (Delta - cos((twoPI * iK)/N)) * (X_x + X_z))/N;
|
||||
|
||||
else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
|
||||
|
||||
else if (mporz == 'Z') sumrule = 1.0; // partition function
|
||||
else if (mporz == 'a') sumrule = 1.0;
|
||||
else if (mporz == 'b') sumrule = 1.0;
|
||||
else if (mporz == 'c') sumrule = 1.0;
|
||||
|
||||
else JSCerror("option not implemented in S1_sumrule_factor.");
|
||||
|
||||
return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N
|
||||
}
|
||||
|
||||
|
||||
//DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& AveragingState, DP Chem_Pot, bool fixed_iK, int iKneeded)
|
||||
DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& AveragingState, DP Chem_Pot, int iKmin, int iKmax)
|
||||
{
|
||||
DP sumrule_factor = 1.0;
|
||||
//if (!fixed_iK) {
|
||||
if (iKmin != iKmax) {
|
||||
if (whichDSF == 'Z') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'm')
|
||||
sumrule_factor = 1.0/AveragingState.base.Mdown;
|
||||
else if (whichDSF == 'z') sumrule_factor = 1.0/(0.25 * AveragingState.chain.Nsites);
|
||||
else if (whichDSF == 'p') sumrule_factor = 1.0/(AveragingState.chain.Nsites - AveragingState.base.Mdown);
|
||||
else if (whichDSF == 'a') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'b') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'c') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
||||
|
||||
else JSCerror("whichDSF option not consistent in Sumrule_Factor");
|
||||
}
|
||||
//else if (fixed_iK) {
|
||||
else if (iKmin == iKmax) {
|
||||
if (whichDSF == 'Z') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'm' || whichDSF == 'z' || whichDSF == 'p')
|
||||
//sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, iKneeded);
|
||||
sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, Chem_Pot, iKmax);
|
||||
else if (whichDSF == 'a') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'b') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'c') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
||||
|
||||
else JSCerror("whichDSF option not consistent in Sumrule_Factor");
|
||||
}
|
||||
|
||||
|
||||
|
||||
return(sumrule_factor);
|
||||
}
|
||||
|
||||
|
||||
void Evaluate_F_Sumrule (string prefix, char whichDSF, const Heis_Bethe_State& AveragingState, DP Chem_Pot, int iKmin_ref, int iKmax_ref)
|
||||
{
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
FSR_stringstream << prefix << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
|
||||
ifstream infile;
|
||||
infile.open(RAW_Cstr);
|
||||
if(infile.fail()) JSCerror("Could not open raw input file in Evaluate_F_Sumrule(Heis...).");
|
||||
|
||||
int iKmin = 0;
|
||||
int iKmax = AveragingState.chain.Nsites;
|
||||
int iKmod = AveragingState.chain.Nsites;
|
||||
|
||||
// We run through the data file to chech the f sumrule at each positive momenta:
|
||||
//Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);
|
||||
Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);
|
||||
|
||||
DP omega, ME;
|
||||
int iK, iKexc;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
while (infile.peek() != EOF) {
|
||||
infile >> omega >> iK >> ME >> dev >> label;
|
||||
//if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
|
||||
iKexc = iK;
|
||||
while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
|
||||
while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
|
||||
if (iKexc >= iKmin && iKexc <= iKmax) Sum_omega_MEsq[iKexc - iKmin] += omega * ME * ME;
|
||||
}
|
||||
|
||||
infile.close();
|
||||
|
||||
ofstream outfile;
|
||||
outfile.open(FSR_Cstr);
|
||||
outfile.precision(16);
|
||||
|
||||
DP X_x = X_avg ('x', AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown);
|
||||
DP X_z = X_avg ('z', AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown);
|
||||
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
if (i > iKmin) outfile << endl;
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i] * S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, Chem_Pot, X_x, X_z, i);
|
||||
}
|
||||
|
||||
outfile.close();
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,139 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c) 2006-9.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: M_vs_H.cc
|
||||
|
||||
Purpose: field to and from magnetization for Heisenberg
|
||||
|
||||
Last modified: 21/10/09
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
DP Ezero (DP Delta, int N, int M)
|
||||
{
|
||||
// Returns the energy of the ground state with M down spins
|
||||
|
||||
if (M < 0 || M > N/2) JSCerror("M out of bounds in Ezero.");
|
||||
|
||||
DP E = -1.0; // sentinel value
|
||||
|
||||
if (M == 0) E = N * Delta/4.0;
|
||||
|
||||
else {
|
||||
|
||||
Heis_Chain BD1(1.0, Delta, 0.0, N);
|
||||
|
||||
Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
|
||||
|
||||
Nrapidities_groundstate[0] = M;
|
||||
|
||||
Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
|
||||
|
||||
if ((Delta > 0.0) && (Delta < 1.0)) {
|
||||
XXZ_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else if (Delta == 1.0) {
|
||||
XXX_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else if (Delta > 1.0) {
|
||||
XXZ_gpd_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else JSCerror("Anisotropy out of bounds in Ezero.");
|
||||
}
|
||||
|
||||
return(E);
|
||||
}
|
||||
|
||||
DP H_vs_M (DP Delta, int N, int M)
|
||||
{
|
||||
// Assumes dE/dM = 0 = dE_0/dM + h, with dE_0/dM = E_0(M) - E_0 (M - 1)
|
||||
|
||||
DP H = 0.0;
|
||||
|
||||
if (2*M == N) H = 0.0;
|
||||
|
||||
else if (Delta <= 1.0) H = Ezero (Delta, N, M - 1) - Ezero (Delta, N, M);
|
||||
|
||||
return(H);
|
||||
}
|
||||
|
||||
DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref)
|
||||
{
|
||||
if (M < 0 || M > N/2 - 1) {
|
||||
cout << "M = " << M << endl;
|
||||
JSCerror("M out of bounds in HZmin.");
|
||||
}
|
||||
|
||||
if (Ezero_ref[M] == -1.0) Ezero_ref[M] = Ezero(Delta, N, M);
|
||||
if (Ezero_ref[M + 1] == -1.0) Ezero_ref[M + 1] = Ezero(Delta, N, M + 1);
|
||||
|
||||
return(Ezero_ref[M] - Ezero_ref[M + 1]);
|
||||
}
|
||||
|
||||
int M_vs_H (DP Delta, int N, DP HZ)
|
||||
{
|
||||
// Returns the value of M for given field HZ
|
||||
|
||||
if (HZ < 0.0) JSCerror("Please use a positive field in M_vs_H.");
|
||||
|
||||
else if (HZ == 0.0) return(N/2);
|
||||
|
||||
// Here, -1.0 is a sentinel value.
|
||||
Vect_DP Ezero(-1.0, N/2 + 1); // contains the GSE[M].
|
||||
|
||||
// We look for M s.t. HZmin[M] < HZ <= HZmin[M + 1]
|
||||
|
||||
int M_actual = N/4; // start somewhere in middle
|
||||
int M_step = N/8 - 1; // step
|
||||
DP HZmin_actual = 0.0;
|
||||
DP HZmax_actual = 0.0;
|
||||
bool M_found = false;
|
||||
|
||||
if (HZ >= 1.0 + Delta) M_actual = 0; // saturation
|
||||
|
||||
else {
|
||||
|
||||
HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
|
||||
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
|
||||
|
||||
while (!M_found) {
|
||||
|
||||
if (HZmin_actual > HZ) M_actual += M_step;
|
||||
else if (HZmax_actual <= HZ) M_actual -= M_step;
|
||||
|
||||
M_step = (M_step + 1)/2;
|
||||
|
||||
HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
|
||||
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
|
||||
|
||||
M_found = (HZmin_actual < HZ && HZ <= HZmax_actual);
|
||||
|
||||
//cout << "M_actual = " << M_actual << "\tM_step = " << M_step
|
||||
// << "\tHZmin_actual = " << HZmin_actual << "\tHZmax_actual = " << HZmax_actual << "\tHZ = " << HZ << "\t" << M_found << endl;
|
||||
}
|
||||
}
|
||||
//cout << "M found = " << M_actual << "\tHZmax = " << Ezero[M_actual] - Ezero[M_actual + 1] << "\tHZmin = " << Ezero[M_actual - 1] - Ezero[M_actual] << endl;
|
||||
|
||||
return(M_actual);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,626 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/XXX_Bethe_State.cc
|
||||
|
||||
Purpose: Defines all functions for XXX_Bethe_State
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// Function prototypes
|
||||
|
||||
DP Theta_XXX (DP lambda, int nj, int nk);
|
||||
DP ddlambda_Theta_XXX (DP lambda, int nj, int nk);
|
||||
|
||||
//***************************************************************************************************
|
||||
|
||||
// Function definitions: class XXX_Bethe_State
|
||||
|
||||
XXX_Bethe_State::XXX_Bethe_State ()
|
||||
: Heis_Bethe_State()
|
||||
{};
|
||||
|
||||
XXX_Bethe_State::XXX_Bethe_State (const XXX_Bethe_State& RefState) // copy constructor
|
||||
: Heis_Bethe_State(RefState)
|
||||
{
|
||||
}
|
||||
|
||||
XXX_Bethe_State::XXX_Bethe_State (const Heis_Chain& RefChain, int M)
|
||||
: Heis_Bethe_State(RefChain, M)
|
||||
{
|
||||
if (RefChain.Delta != 1.0) {
|
||||
cout << setprecision(16) << RefChain.Delta << endl;
|
||||
JSCerror("Delta != 1.0 in XXX_Bethe_State constructor");
|
||||
}
|
||||
}
|
||||
|
||||
XXX_Bethe_State::XXX_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase)
|
||||
: Heis_Bethe_State(RefChain, RefBase)
|
||||
{
|
||||
if (RefChain.Delta != 1.0) {
|
||||
cout << setprecision(16) << RefChain.Delta << endl;
|
||||
JSCerror("Delta != 1.0 in XXX_Bethe_State constructor");
|
||||
}
|
||||
}
|
||||
/*
|
||||
XXX_Bethe_State::XXX_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
|
||||
: Heis_Bethe_State(RefChain, base_id_ref, type_id_ref)
|
||||
{
|
||||
if (RefChain.Delta != 1.0) {
|
||||
cout << setprecision(16) << RefChain.Delta << endl;
|
||||
JSCerror("Delta != 1.0 in XXX_Bethe_State constructor");
|
||||
}
|
||||
}
|
||||
*/
|
||||
XXX_Bethe_State& XXX_Bethe_State::operator= (const XXX_Bethe_State& RefState)
|
||||
{
|
||||
if (this != &RefState) {
|
||||
chain = RefState.chain;
|
||||
base = RefState.base;
|
||||
//offsets = RefState.offsets;
|
||||
Ix2 = RefState.Ix2;
|
||||
lambda = RefState.lambda;
|
||||
BE = RefState.BE;
|
||||
diffsq = RefState.diffsq;
|
||||
conv = RefState.conv;
|
||||
iter = RefState.iter;
|
||||
iter_Newton = RefState.iter_Newton;
|
||||
E = RefState.E;
|
||||
iK = RefState.iK;
|
||||
K = RefState.K;
|
||||
lnnorm = RefState.lnnorm;
|
||||
//base_id = RefState.base_id;
|
||||
//type_id = RefState.type_id;
|
||||
//id = RefState.id;
|
||||
//maxid = RefState.maxid;
|
||||
//nparticles = RefState.nparticles;
|
||||
label = RefState.label;
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
// Member functions
|
||||
|
||||
void XXX_Bethe_State::Set_Free_lambdas()
|
||||
{
|
||||
// Sets all the rapidities to the solutions of the BAEs without scattering terms
|
||||
|
||||
for (int i = 0; i < chain.Nstrings; ++i) {
|
||||
|
||||
for (int alpha = 0; alpha < base[i]; ++alpha) {
|
||||
|
||||
lambda[i][alpha] = chain.Str_L[i] * 0.5 * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool XXX_Bethe_State::Check_Admissibility(char option)
|
||||
{
|
||||
// This function checks the admissibility of the Ix2's of a state:
|
||||
// returns false if there are higher strings with Ix2 = 0, a totally symmetric distribution of I's at each level,
|
||||
// and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE.
|
||||
|
||||
bool answer = true;
|
||||
//int test1, test3;
|
||||
Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
|
||||
|
||||
bool higher_string_on_zero = false;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
// The following line puts answer to true if there is at least one higher string with zero Ix2
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] > 2) && !(chain.Str_L[j] % 2))
|
||||
higher_string_on_zero = true;
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
|
||||
// NOTE: if base[j] == 0, Zero_at_level[j] remains false.
|
||||
}
|
||||
|
||||
bool symmetric_state = (*this).Check_Symmetry();
|
||||
|
||||
bool string_coincidence = false;
|
||||
// Checks that we have strings of equal length modulo 2 with Ix2 == 0, so equal rapidities, and inadmissibility
|
||||
for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
|
||||
for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
|
||||
if (Zero_at_level[j1] && Zero_at_level[j2] && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
|
||||
string_coincidence = true;
|
||||
}
|
||||
/*
|
||||
bool onep_onem_on_zero = false;
|
||||
if (option == 'm') { // for Smin, we also exclude symmetric states with 1+ and 1- strings on zero
|
||||
if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
|
||||
}
|
||||
*/
|
||||
answer = !(symmetric_state && (higher_string_on_zero || string_coincidence /*|| onep_onem_on_zero*/));
|
||||
|
||||
// Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
|
||||
|
||||
if (!answer) {
|
||||
E = 0.0;
|
||||
K = 0.0;
|
||||
conv = 0;
|
||||
iter = 0;
|
||||
iter_Newton = 0;
|
||||
lnnorm = -100.0;
|
||||
}
|
||||
|
||||
return(answer); // answer == true: nothing wrong with this Ix2_config
|
||||
}
|
||||
|
||||
void XXX_Bethe_State::Compute_BE (int j, int alpha)
|
||||
{
|
||||
// Fills in the BE members with the value of the Bethe equations.
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += atan(lambda[j][alpha] - lambda[k][beta]);
|
||||
|
||||
else sumtheta += 0.5 * Theta_XXX((lambda[j][alpha] - lambda[k][beta]), chain.Str_L[j], chain.Str_L[k]);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = 2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
}
|
||||
|
||||
void XXX_Bethe_State::Compute_BE ()
|
||||
{
|
||||
// Fills in the BE members with the value of the Bethe equations.
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += atan(lambda[j][alpha] - lambda[k][beta]);
|
||||
|
||||
else sumtheta += 0.5 * Theta_XXX((lambda[j][alpha] - lambda[k][beta]), chain.Str_L[j], chain.Str_L[k]);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = 2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DP XXX_Bethe_State::Iterate_BAE (int j, int alpha)
|
||||
{
|
||||
// Returns a new iteration value for lambda[j][alpha] given BE[j][alpha]
|
||||
|
||||
return(0.5 * chain.Str_L[j] * tan(0.5 *
|
||||
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
|
||||
(2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - BE[j][alpha])
|
||||
));
|
||||
}
|
||||
|
||||
/*
|
||||
void XXX_Bethe_State::Iterate_BAE ()
|
||||
{
|
||||
// Recalculates the rapidities by iterating Bethe equations
|
||||
|
||||
Lambda New_lambda(chain, base);
|
||||
DP sumtheta = 0.0;
|
||||
DP arg = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += atan(lambda[j][alpha] - lambda[k][beta]);
|
||||
|
||||
else sumtheta += 0.5 * Theta_XXX(lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k]);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
New_lambda[j][alpha] = 0.5 * chain.Str_L[j] * tan((PI * 0.5 * Ix2[j][alpha] + 0.5 * sumtheta)/chain.Nsites);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DP New_diffsq = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
New_diffsq += pow(New_lambda[j][alpha] - lambda[j][alpha], 2.0);
|
||||
lambda[j][alpha] = 1.0 * New_lambda[j][alpha] + 0.0 * lambda[j][alpha];
|
||||
}
|
||||
}
|
||||
|
||||
diffsq = New_diffsq;
|
||||
iter++;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void XXX_Bethe_State::Iterate_BAE_Newton ()
|
||||
{
|
||||
// does one step of a Newton method on the rapidities...
|
||||
|
||||
Vect_DP RHSBAE (0.0, base.Nraptot); // contains RHS of BAEs
|
||||
Vect_CX dlambda (0.0, base.Nraptot); // contains delta lambda computed from Newton's method
|
||||
SQMat_CX Gaudin (0.0, base.Nraptot);
|
||||
Vect_INT indx (base.Nraptot);
|
||||
DP sumtheta = 0.0;
|
||||
DP arg = 0.0;
|
||||
DP fn_arg = 0.0;
|
||||
DP olddiffsq = diffsq;
|
||||
|
||||
// Compute the RHS of the BAEs:
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += atan(lambda[j][alpha] - lambda[k][beta]);
|
||||
|
||||
else sumtheta += 0.5 * Theta_XXX((lambda[j][alpha] - lambda[k][beta]), chain.Str_L[j], chain.Str_L[k]);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
RHSBAE[index] = chain.Nsites * 2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - sumtheta - PI*Ix2[j][alpha];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
(*this).Build_Reduced_Gaudin_Matrix (Gaudin);
|
||||
|
||||
for (int i = 0; i < base.Nraptot; ++i) dlambda[i] = - RHSBAE[i];
|
||||
|
||||
DP d;
|
||||
ludcmp_CX (Gaudin, indx, d);
|
||||
lubksb_CX (Gaudin, indx, dlambda);
|
||||
|
||||
diffsq = 0.0;
|
||||
for (int i = 0; i < base.Nraptot; ++i) diffsq += norm(dlambda[i]);
|
||||
|
||||
// if we've converged, calculate the norm here, since the work has been done...
|
||||
|
||||
if (diffsq < chain.prec) {
|
||||
lnnorm = 0.0;
|
||||
for (int j = 0; j < base.Nraptot; j++) lnnorm += log(abs(Gaudin[j][j]));
|
||||
}
|
||||
|
||||
index = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
lambda[j][alpha] += real(dlambda[index]);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
iter_Newton++;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
bool XXX_Bethe_State::Check_Rapidities()
|
||||
{
|
||||
bool nonan = true;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) nonan *= !is_nan(lambda[j][alpha]);
|
||||
|
||||
return nonan;
|
||||
}
|
||||
|
||||
DP XXX_Bethe_State::String_delta ()
|
||||
{
|
||||
// Computes the sum of absolute value of \delta^{a, a+1} in string hypothesis, for a given Bethe eigenstate
|
||||
|
||||
DP delta = 0.0;
|
||||
|
||||
int occupied_strings = 0;
|
||||
for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
|
||||
|
||||
//if ((*this).conv == 0) delta = 1.0;
|
||||
|
||||
if (occupied_strings == 0) delta = 0.0;
|
||||
|
||||
else {
|
||||
|
||||
Vect_DP ln_deltadiff(0.0, 1000); // contains ln |delta^{a, a+1}|
|
||||
Vect_DP deltadiff(0.0, 1000); // contains |delta^{a, a+1}|
|
||||
|
||||
complex<DP> log_BAE_reg = 0.0;
|
||||
|
||||
for (int j = 0; j < (*this).chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < (*this).base[j]; ++alpha) {
|
||||
|
||||
ln_deltadiff = 0.0;
|
||||
|
||||
for (int a = 1; a <= (*this).chain.Str_L[j]; ++a) {
|
||||
|
||||
if ((*this).chain.Str_L[j] > 1) { // else the BAE are already 1
|
||||
|
||||
log_BAE_reg = DP((*this).chain.Nsites) * log(((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0))
|
||||
/((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int k = 0; k < (*this).chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < (*this).base[k]; ++beta)
|
||||
for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
|
||||
if ((j != k) || (alpha != beta) || (a != b - 1))
|
||||
|
||||
log_BAE_reg += log((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
|
||||
) - II );
|
||||
|
||||
if ((j != k) || (alpha != beta) || (a != b + 1))
|
||||
|
||||
log_BAE_reg -= log(((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
|
||||
)
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
|
||||
) + II );
|
||||
}
|
||||
|
||||
// The regular LHS of BAE is now defined. Now sum up the deltas...
|
||||
|
||||
if (a == 1) ln_deltadiff[0] = - real(log_BAE_reg);
|
||||
|
||||
else if (a < (*this).chain.Str_L[j]) ln_deltadiff[a - 1] = ln_deltadiff[a-2] - real(log_BAE_reg);
|
||||
|
||||
else if (a == (*this).chain.Str_L[j]) ln_deltadiff[a-1] = real(log_BAE_reg);
|
||||
|
||||
} // if ((*this).chain.Str_L[j] > 1)
|
||||
|
||||
} // for (int a = 1; ...
|
||||
|
||||
for (int a = 0; a < (*this).chain.Str_L[j]; ++a) {
|
||||
deltadiff[a] = ln_deltadiff[a] != 0.0 ? exp(ln_deltadiff[a]) : 0.0;
|
||||
delta += fabs(deltadiff[a]);
|
||||
}
|
||||
|
||||
} // alpha sum
|
||||
} // j sum
|
||||
|
||||
if (is_nan(delta)) delta = 1.0; // sentinel
|
||||
|
||||
} // else
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
void XXX_Bethe_State::Compute_Energy ()
|
||||
{
|
||||
DP sum = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum += chain.Str_L[j] / ( 4.0 * lambda[j][alpha] * lambda[j][alpha] + chain.Str_L[j] * chain.Str_L[j]);
|
||||
}
|
||||
}
|
||||
|
||||
sum *= - chain.J * 2.0;
|
||||
|
||||
E = sum;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
void XXX_Bethe_State::Compute_Momentum ()
|
||||
{
|
||||
int sum_Ix2 = 0;
|
||||
DP sum_M = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
sum_M += base[j];
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum_Ix2 += Ix2[j][alpha];
|
||||
}
|
||||
}
|
||||
|
||||
iK = (chain.Nsites/2) * int(sum_M) - (sum_Ix2/2);
|
||||
|
||||
while (iK >= chain.Nsites) iK -= chain.Nsites;
|
||||
while (iK < 0) iK += chain.Nsites;
|
||||
|
||||
K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
|
||||
|
||||
while (K >= 2.0*PI) K -= 2.0*PI;
|
||||
while (K < 0.0) K += 2.0*PI;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
void XXX_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
|
||||
{
|
||||
|
||||
if (Gaudin_Red.size() != base.Nraptot) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
|
||||
int index_jalpha;
|
||||
int index_kbeta;
|
||||
|
||||
DP sum_hbar_XXX = 0.0;
|
||||
|
||||
index_jalpha = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
index_kbeta = 0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta) {
|
||||
|
||||
if ((j == k) && (alpha == beta)) {
|
||||
|
||||
sum_hbar_XXX = 0.0;
|
||||
|
||||
for (int kp = 0; kp < chain.Nstrings; ++kp) {
|
||||
for (int betap = 0; betap < base[kp]; ++betap) {
|
||||
if (!((j == kp) && (alpha == betap)))
|
||||
sum_hbar_XXX
|
||||
+= ddlambda_Theta_XXX (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp]);
|
||||
}
|
||||
}
|
||||
|
||||
Gaudin_Red[index_jalpha][index_kbeta]
|
||||
= complex<DP> ( chain.Nsites * chain.Str_L[j]/(lambda[j][alpha] * lambda[j][alpha] + 0.25 * chain.Str_L[j] * chain.Str_L[j])
|
||||
- sum_hbar_XXX);
|
||||
}
|
||||
|
||||
else {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
Gaudin_Red[index_jalpha][index_kbeta] =
|
||||
complex<DP> ( 2.0/(pow(lambda[j][alpha] - lambda[k][beta], 2.0) + 1.0));
|
||||
|
||||
else
|
||||
Gaudin_Red[index_jalpha][index_kbeta] =
|
||||
complex<DP> (ddlambda_Theta_XXX (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k]));
|
||||
}
|
||||
index_kbeta++;
|
||||
}
|
||||
}
|
||||
index_jalpha++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool XXX_Bethe_State::Check_Finite_rap ()
|
||||
{
|
||||
bool answer = true;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
if (fabs(lambda[j][alpha]) > 1.0e6) answer = false;
|
||||
}
|
||||
}
|
||||
|
||||
return(answer);
|
||||
}
|
||||
|
||||
// ****************************************************************************************************
|
||||
|
||||
// non-member functions
|
||||
|
||||
DP Theta_XXX (DP lambda, int nj, int nk)
|
||||
{
|
||||
DP result;
|
||||
|
||||
if ((nj == 1) && (nk == 1)) result = 2.0 * atan(lambda);
|
||||
|
||||
else {
|
||||
|
||||
result = (nj == nk) ? 0.0 : 2.0 * atan(2.0 * lambda/fabs(nj - nk));
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 4.0 * atan(2.0 * lambda/(fabs(nj - nk) + 2*a));
|
||||
|
||||
result += 2.0 * atan(2.0 * lambda/(nj + nk));
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DP ddlambda_Theta_XXX (DP lambda, int nj, int nk)
|
||||
{
|
||||
int n = abs(nj - nk);
|
||||
|
||||
DP result = (nj == nk) ? 0.0 : DP(n)/(lambda * lambda + 0.25 * n * n);
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * (n + 2.0*a)
|
||||
/ (lambda * lambda + 0.25 * (n + 2.0*a) * (n + 2.0*a));
|
||||
|
||||
result += DP(nj + nk)/(lambda * lambda + 0.25 * (nj + nk) * (nj + nk));
|
||||
|
||||
return (result);
|
||||
}
|
||||
/*
|
||||
DP ddlambda_Theta_XXX (DP lambda, int nj, int nk)
|
||||
{
|
||||
DP result = (nj == nk) ? 0.0 : DP(nj - nk)/(lambda * lambda + 0.25 * (nj - nk) * (nj - nk));
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * (nj - nk + 2.0*a) * (nj - nk + 2.0*a)
|
||||
/ (lambda * lambda + 0.25 * (nj - nk + 2.0*a) * (nj - nk + 2.0*a));
|
||||
|
||||
result += DP(nj + nk)/(lambda * lambda + 0.25 * (nj + nk) * (nj + nk));
|
||||
|
||||
return (result);
|
||||
}
|
||||
*/
|
||||
|
||||
XXX_Bethe_State Add_Particle_at_Center (const XXX_Bethe_State& RefState)
|
||||
{
|
||||
if (2*RefState.base.Mdown == RefState.chain.Nsites)
|
||||
JSCerror("Trying to add a down spin to a zero-magnetized chain in Add_Particle_at_Center.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] + 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXX_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Add a quantum number in middle (explicitly: to right of index M[0]/2)
|
||||
// and shift quantum numbers by half-integer away from added one:
|
||||
ReturnState.Ix2[0][RefState.base.Nrap[0]/2] = RefState.Ix2[0][RefState.base.Nrap[0]/2] - 1;
|
||||
for (int i = 0; i < RefState.base.Nrap[0] + 1; ++i)
|
||||
ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] = RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
|
||||
XXX_Bethe_State Remove_Particle_at_Center (const XXX_Bethe_State& RefState)
|
||||
{
|
||||
if (RefState.base.Nrap[0] == 0)
|
||||
JSCerror("Trying to remove a down spin in an empty Nrap[0] state.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] - 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXX_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Remove midmost and shift quantum numbers by half-integer towards removed one:
|
||||
for (int i = 0; i < RefState.base.Nrap[0]-1; ++i)
|
||||
ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,646 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/XXZ_Bethe_State.cc
|
||||
|
||||
Purpose: Defines all functions for XXZ_Bethe_State
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// Function prototypes
|
||||
|
||||
inline DP fbar_XXZ (DP lambda, int par, DP tannzetaover2);
|
||||
DP Theta_XXZ (DP lambda, int nj, int nk, int parj, int park, DP* tannzetaover2);
|
||||
DP hbar_XXZ (DP lambda, int n, int par, DP* si_n_anis_over_2);
|
||||
DP ddlambda_Theta_XXZ (DP lambda, int nj, int nk, int parj, int park, DP* si_n_anis_over_2);
|
||||
|
||||
|
||||
//***************************************************************************************************
|
||||
|
||||
// Function definitions: class XXZ_Bethe_State
|
||||
|
||||
XXZ_Bethe_State::XXZ_Bethe_State ()
|
||||
: Heis_Bethe_State(), sinhlambda(Lambda(chain, 1)), coshlambda(Lambda(chain, 1)), tanhlambda(Lambda(chain, 1))
|
||||
{};
|
||||
|
||||
XXZ_Bethe_State::XXZ_Bethe_State (const XXZ_Bethe_State& RefState) // copy constructor
|
||||
: Heis_Bethe_State(RefState), sinhlambda(Lambda(RefState.chain, RefState.base)), coshlambda(Lambda(RefState.chain, RefState.base)),
|
||||
tanhlambda(Lambda(RefState.chain, RefState.base))
|
||||
{
|
||||
// copy arrays into new ones
|
||||
|
||||
//cout << "Calling XXZ state copy constructor." << endl;
|
||||
for (int j = 0; j < RefState.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < RefState.base[j]; ++j) {
|
||||
sinhlambda[j][alpha] = RefState.sinhlambda[j][alpha];
|
||||
coshlambda[j][alpha] = RefState.coshlambda[j][alpha];
|
||||
tanhlambda[j][alpha] = RefState.tanhlambda[j][alpha];
|
||||
}
|
||||
}
|
||||
//cout << "Done calling XXZ state copy constructor." << endl;
|
||||
}
|
||||
|
||||
XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, int M)
|
||||
: Heis_Bethe_State(RefChain, M),
|
||||
sinhlambda(Lambda(RefChain, M)), coshlambda(Lambda(RefChain, M)), tanhlambda(Lambda(RefChain, M))
|
||||
{
|
||||
//cout << "Here in XXZ BS constructor." << endl;
|
||||
//cout << (*this).lambda[0][0] << endl;
|
||||
//cout << "OK" << endl;
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) JSCerror("Delta out of range in XXZ_Bethe_State constructor");
|
||||
}
|
||||
|
||||
XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase)
|
||||
: Heis_Bethe_State(RefChain, RefBase),
|
||||
sinhlambda(Lambda(RefChain, RefBase)), coshlambda(Lambda(RefChain, RefBase)), tanhlambda(Lambda(RefChain, RefBase))
|
||||
{
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) JSCerror("Delta out of range in XXZ_Bethe_State constructor");
|
||||
}
|
||||
/*
|
||||
XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
|
||||
: Heis_Bethe_State(RefChain, base_id_ref, type_id_ref),
|
||||
sinhlambda(Lambda(chain, base)), coshlambda(Lambda(chain, base)), tanhlambda(Lambda(chain, base))
|
||||
{
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) JSCerror("Delta out of range in XXZ_Bethe_State constructor");
|
||||
}
|
||||
*/
|
||||
|
||||
XXZ_Bethe_State& XXZ_Bethe_State::operator= (const XXZ_Bethe_State& RefState)
|
||||
{
|
||||
if (this != &RefState) {
|
||||
chain = RefState.chain;
|
||||
base = RefState.base;
|
||||
//offsets = RefState.offsets;
|
||||
Ix2 = RefState.Ix2;
|
||||
lambda = RefState.lambda;
|
||||
BE = RefState.BE;
|
||||
diffsq = RefState.diffsq;
|
||||
conv = RefState.conv;
|
||||
iter = RefState.iter;
|
||||
iter_Newton = RefState.iter_Newton;
|
||||
E = RefState.E;
|
||||
iK = RefState.iK;
|
||||
K = RefState.K;
|
||||
lnnorm = RefState.lnnorm;
|
||||
//base_id = RefState.base_id;
|
||||
//type_id = RefState.type_id;
|
||||
//id = RefState.id;
|
||||
//maxid = RefState.maxid;
|
||||
//nparticles = RefState.nparticles;
|
||||
label = RefState.label;
|
||||
|
||||
sinhlambda = RefState.sinhlambda;
|
||||
coshlambda = RefState.coshlambda;
|
||||
tanhlambda = RefState.tanhlambda;
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
// Member functions
|
||||
|
||||
void XXZ_Bethe_State::Set_Free_lambdas()
|
||||
{
|
||||
// Sets all the rapidities to the solutions of the BAEs without scattering terms
|
||||
|
||||
DP x = 0.0;
|
||||
for (int i = 0; i < chain.Nstrings; ++i) {
|
||||
|
||||
for (int alpha = 0; alpha < base[i]; ++alpha) {
|
||||
|
||||
if (chain.par[i] == 1) {
|
||||
//lambda[i][alpha] = atanh(tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites));
|
||||
x = tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites);
|
||||
lambda[i][alpha] = atanh(x/sqrt(1.0 + x*x)); // lambda then always initiated real
|
||||
}
|
||||
|
||||
else if (chain.par[i] == -1) {
|
||||
//lambda[i][alpha] = atanh(-tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis));
|
||||
x = -tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis);
|
||||
lambda[i][alpha] = atanh(x/sqrt(1.0 + x*x)); // lambda then always initiated real
|
||||
}
|
||||
|
||||
else JSCerror("Invalid parities in Set_Free_lambdas.");
|
||||
//cout << tan(chain.Str_L[i] * 0.5 * chain.anis) << endl;
|
||||
//cout << "Set_Free_lambdas: " << i << "\t" << alpha << "\t" << lambda[i][alpha] << "\t" << tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites) << endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_Bethe_State::Compute_sinhlambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) sinhlambda[j][alpha] = sinh(lambda[j][alpha]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_Bethe_State::Compute_coshlambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) coshlambda[j][alpha] = cosh(lambda[j][alpha]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_Bethe_State::Compute_tanhlambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) tanhlambda[j][alpha] = tanh(lambda[j][alpha]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool XXZ_Bethe_State::Check_Admissibility(char option)
|
||||
{
|
||||
// This function checks the admissibility of the Ix2's of a state:
|
||||
// returns false if there are higher strings with Ix2 = 0, a totally symmetric distribution of I's at each level,
|
||||
// and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE.
|
||||
|
||||
bool answer = true;
|
||||
Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
|
||||
|
||||
bool higher_string_on_zero = false;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
// The following line puts answer to true if there is at least one higher string with zero Ix2
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] >= 2) /*&& !(chain.Str_L[j] % 2)*/)
|
||||
higher_string_on_zero = true;
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
|
||||
// NOTE: if base[j] == 0, Zero_at_level[j] remains false.
|
||||
}
|
||||
|
||||
// check symmetry of Ix2 at each level, if there exists a potentially risky Ix2...
|
||||
|
||||
bool symmetric_state = (*this).Check_Symmetry();
|
||||
|
||||
bool string_coincidence = false;
|
||||
for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
|
||||
for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
|
||||
if (Zero_at_level[j1] && Zero_at_level[j2] && (chain.par[j1] == chain.par[j2]) && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
|
||||
string_coincidence = true;
|
||||
}
|
||||
|
||||
bool M_odd_and_onep_on_zero = false;
|
||||
if (option == 'z') { // for Sz, if M is odd, exclude symmetric states with a 1+ on zero
|
||||
// (zero rapidities in left and right states, so FF det not defined).
|
||||
bool is_ground_state = base.Nrap[0] == base.Mdown && Ix2[0][0] == -(base.Mdown - 1) && Ix2[0][base.Mdown-1] == base.Mdown - 1;
|
||||
if (Zero_at_level[0] && (base.Mdown % 2) && !is_ground_state) M_odd_and_onep_on_zero = true;
|
||||
}
|
||||
|
||||
bool onep_onem_on_zero = false;
|
||||
if (option == 'm' || option == 'p') { // for Smin, we also exclude symmetric states with 1+ and 1- strings on zero
|
||||
if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
|
||||
}
|
||||
|
||||
answer = !(symmetric_state && (higher_string_on_zero || string_coincidence || onep_onem_on_zero || M_odd_and_onep_on_zero));
|
||||
|
||||
// Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
|
||||
|
||||
if (!answer) {
|
||||
E = 0.0;
|
||||
K = 0.0;
|
||||
conv = 0;
|
||||
iter = 0;
|
||||
iter_Newton = 0;
|
||||
lnnorm = -100.0;
|
||||
}
|
||||
|
||||
return(answer); // answer == true: nothing wrong with this Ix2_config
|
||||
}
|
||||
|
||||
void XXZ_Bethe_State::Compute_BE (int j, int alpha)
|
||||
{
|
||||
tanhlambda[j][alpha] = tanh(lambda[j][alpha]);
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
for (int k = 0; k < chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < base[k]; ++beta) {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += (chain.par[j] == chain.par[k])
|
||||
? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
|
||||
: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
|
||||
else sumtheta += 0.5 * Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
: -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
|
||||
}
|
||||
|
||||
void XXZ_Bethe_State::Compute_BE ()
|
||||
{
|
||||
// Fills in the BE members with the value of the Bethe equations.
|
||||
|
||||
(*this).Compute_tanhlambda();
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < base[k]; ++beta) {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += (chain.par[j] == chain.par[k])
|
||||
? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
|
||||
: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
|
||||
else sumtheta += 0.5 * Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
: -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
|
||||
//if (is_nan(BE[j][alpha])) cout << "BE nan: " << j << "\t" << alpha << "\t" << lambda[j][alpha] << "\t" << tanhlambda[j][alpha] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
DP XXZ_Bethe_State::Iterate_BAE (int j, int alpha)
|
||||
{
|
||||
// Returns a new iteration value for lambda[j][alpha] given tanhlambda and BE Lambdas
|
||||
// Assumes that tanhlambda[][] and BE[][] have been computed.
|
||||
|
||||
DP new_lambda = 0.0;
|
||||
DP arg = 0.0;
|
||||
|
||||
if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]]
|
||||
* tan(0.5 *
|
||||
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
|
||||
(2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha])
|
||||
);
|
||||
|
||||
else if (chain.par[j] == -1) arg = -tan(0.5 *
|
||||
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites)
|
||||
(-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha]))
|
||||
/chain.ta_n_anis_over_2[chain.Str_L[j]];
|
||||
|
||||
if (fabs(arg) < 1.0) {
|
||||
new_lambda = atanh(arg);
|
||||
}
|
||||
|
||||
else {
|
||||
new_lambda = lambda[j][alpha]; // back to drawing board...
|
||||
int block = 0; // counter to prevent runaway while loop
|
||||
DP new_tanhlambda = 0.0;
|
||||
DP sumtheta = 0.0;
|
||||
arg = 10.0; // reset value to start while loop
|
||||
while ((fabs(arg) > 1.0) && (block++ < 100)) { // recompute the diverging root on its own...
|
||||
new_lambda *= 1.01; // try to go slowly towards infinity...
|
||||
new_tanhlambda = tanh(new_lambda);
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += (chain.par[j] == chain.par[k])
|
||||
? atan((new_tanhlambda - tanhlambda[k][beta])/((1.0 - new_tanhlambda * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
|
||||
: - atan(((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
|
||||
else sumtheta += 0.5 * Theta_XXZ((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(0.5 * (PI * Ix2[j][alpha] + sumtheta)/chain.Nsites);
|
||||
|
||||
else if (chain.par[j] == -1) arg = -tan(0.5 * (PI * Ix2[j][alpha] + sumtheta)/chain.Nsites)/chain.ta_n_anis_over_2[chain.Str_L[j]];
|
||||
|
||||
else JSCerror("Invalid parities in Iterate_BAE.");
|
||||
|
||||
}
|
||||
|
||||
if (fabs(arg) < 1.0) {
|
||||
new_lambda = atanh(arg);
|
||||
}
|
||||
|
||||
//else cout << "Rapidity blows up !\t" << lambda[j][alpha] << "\t" << new_lambda << endl;
|
||||
} // else
|
||||
|
||||
return(new_lambda);
|
||||
}
|
||||
|
||||
bool XXZ_Bethe_State::Check_Rapidities()
|
||||
{
|
||||
bool nonan = true;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) nonan *= !is_nan(lambda[j][alpha]);
|
||||
|
||||
return nonan;
|
||||
}
|
||||
|
||||
DP XXZ_Bethe_State::String_delta ()
|
||||
{
|
||||
// Computes the sum of absolute value of \delta^{a, a+1} in string hypothesis, for a given bethe eigenstate
|
||||
|
||||
DP delta = 0.0;
|
||||
|
||||
int occupied_strings = 0;
|
||||
for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
|
||||
|
||||
//if ((*this).conv == 0) delta = 1.0;
|
||||
|
||||
if (occupied_strings == 0) delta = 0.0;
|
||||
|
||||
else {
|
||||
|
||||
Vect_DP ln_deltadiff(0.0, 1000); // contains ln |delta^{a, a+1}|
|
||||
Vect_DP deltadiff(0.0, 1000); // contains |delta^{a, a+1}|
|
||||
|
||||
complex<DP> log_BAE_reg = 0.0;
|
||||
|
||||
for (int j = 0; j < (*this).chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < (*this).base[j]; ++alpha) {
|
||||
|
||||
ln_deltadiff = 0.0;
|
||||
|
||||
for (int a = 1; a <= (*this).chain.Str_L[j]; ++a) {
|
||||
|
||||
if ((*this).chain.Str_L[j] > 1) { // else the BAE are already 1
|
||||
|
||||
log_BAE_reg = DP((*this).chain.Nsites) * log(sinh((*this).lambda[j][alpha]
|
||||
+ 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
|
||||
/sinh((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j])));
|
||||
|
||||
for (int k = 0; k < (*this).chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < (*this).base[k]; ++beta)
|
||||
for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
|
||||
if ((j != k) || (alpha != beta) || (a != b - 1))
|
||||
|
||||
log_BAE_reg += log(sinh(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[k])) - II * (*this).chain.anis));
|
||||
|
||||
if ((j != k) || (alpha != beta) || (a != b + 1))
|
||||
|
||||
log_BAE_reg -= log(sinh(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[k])) + II * (*this).chain.anis));
|
||||
}
|
||||
|
||||
// The regular LHS of BAE is now defined. Now sum up the deltas...
|
||||
|
||||
if (a == 1) ln_deltadiff[0] = - real(log_BAE_reg);
|
||||
|
||||
else if (a < (*this).chain.Str_L[j]) ln_deltadiff[a - 1] = ln_deltadiff[a-2] - real(log_BAE_reg);
|
||||
|
||||
else if (a == (*this).chain.Str_L[j]) ln_deltadiff[a-1] = real(log_BAE_reg);
|
||||
|
||||
} // if ((*this).chain.Str_L[j] > 1)
|
||||
|
||||
} // for (int a = 1; ...
|
||||
|
||||
for (int a = 0; a < (*this).chain.Str_L[j]; ++a) {
|
||||
deltadiff[a] = ln_deltadiff[a] != 0.0 ? exp(ln_deltadiff[a]) : 0.0;
|
||||
delta += fabs(deltadiff[a]);
|
||||
}
|
||||
|
||||
} // alpha sum
|
||||
} // j sum
|
||||
|
||||
if (is_nan(delta)) delta = 1.0; // sentinel
|
||||
|
||||
} // else
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
void XXZ_Bethe_State::Compute_Energy ()
|
||||
{
|
||||
DP sum = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum += sin(chain.Str_L[j] * chain.anis) / (chain.par[j] * cosh(2.0 * lambda[j][alpha]) - cos(chain.Str_L[j] * chain.anis));
|
||||
}
|
||||
}
|
||||
|
||||
sum *= - chain.J * sin(chain.anis);
|
||||
|
||||
E = sum;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
void XXZ_Bethe_State::Compute_Momentum ()
|
||||
{
|
||||
int sum_Ix2 = 0;
|
||||
DP sum_M = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
sum_M += 0.5 * (1.0 + chain.par[j]) * base[j];
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum_Ix2 += Ix2[j][alpha];
|
||||
}
|
||||
}
|
||||
|
||||
iK = (chain.Nsites/2) * int(sum_M + 0.1) - (sum_Ix2/2); // + 0.1: for safety...
|
||||
|
||||
while (iK >= chain.Nsites) iK -= chain.Nsites;
|
||||
while (iK < 0) iK += chain.Nsites;
|
||||
|
||||
K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
|
||||
|
||||
while (K >= 2.0*PI) K -= 2.0*PI;
|
||||
while (K < 0.0) K += 2.0*PI;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
void XXZ_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
|
||||
{
|
||||
|
||||
if (Gaudin_Red.size() != base.Nraptot) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
|
||||
int index_jalpha;
|
||||
int index_kbeta;
|
||||
|
||||
DP sum_hbar_XXZ = 0.0;
|
||||
|
||||
DP sinzetasq = pow(sin(chain.anis), 2.0);
|
||||
|
||||
(*this).Compute_sinhlambda();
|
||||
(*this).Compute_coshlambda();
|
||||
|
||||
index_jalpha = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
index_kbeta = 0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta) {
|
||||
|
||||
if ((j == k) && (alpha == beta)) {
|
||||
|
||||
sum_hbar_XXZ = 0.0;
|
||||
|
||||
for (int kp = 0; kp < chain.Nstrings; ++kp) {
|
||||
for (int betap = 0; betap < base[kp]; ++betap) {
|
||||
if (!((j == kp) && (alpha == betap)))
|
||||
sum_hbar_XXZ
|
||||
+= ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp], chain.par[j], chain.par[kp],
|
||||
chain.si_n_anis_over_2);
|
||||
}
|
||||
}
|
||||
|
||||
Gaudin_Red[index_jalpha][index_kbeta]
|
||||
= complex<DP> ( chain.Nsites * hbar_XXZ (lambda[j][alpha], chain.Str_L[j], chain.par[j], chain.si_n_anis_over_2) - sum_hbar_XXZ);
|
||||
}
|
||||
|
||||
else {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
Gaudin_Red[index_jalpha][index_kbeta] =
|
||||
complex<DP> ((chain.par[j] * chain.par[k] == 1)
|
||||
? chain.si_n_anis_over_2[4]/(pow(sinhlambda[j][alpha] * coshlambda[k][beta]
|
||||
- coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq)
|
||||
: chain.si_n_anis_over_2[4]/(-pow(coshlambda[j][alpha] * coshlambda[k][beta]
|
||||
- sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) );
|
||||
else
|
||||
Gaudin_Red[index_jalpha][index_kbeta] = complex<DP> (ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k],
|
||||
chain.par[j], chain.par[k], chain.si_n_anis_over_2));
|
||||
}
|
||||
index_kbeta++;
|
||||
}
|
||||
}
|
||||
index_jalpha++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// ****************************************************************************************************
|
||||
|
||||
// non-member functions
|
||||
|
||||
inline DP fbar_XXZ (DP tanhlambda, int par, DP tannzetaover2)
|
||||
{
|
||||
DP result = 0.0;
|
||||
|
||||
if (par == 1) result = 2.0 * atan(tanhlambda/tannzetaover2);
|
||||
|
||||
else if (par == -1) result = -2.0 * atan(tanhlambda * tannzetaover2);
|
||||
|
||||
else JSCerror("Faulty parity in fbar_XXZ.");
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DP Theta_XXZ (DP tanhlambda, int nj, int nk, int parj, int park, DP* tannzetaover2)
|
||||
{
|
||||
DP result = 0.0;
|
||||
|
||||
if ((nj == 1) && (nk == 1)) result = fbar_XXZ(tanhlambda, parj*park, tannzetaover2[2]);
|
||||
|
||||
else {
|
||||
|
||||
result = (nj == nk) ? 0.0 : fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk)]);
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk) + 2*a]);
|
||||
|
||||
result += fbar_XXZ(tanhlambda, parj*park, tannzetaover2[nj + nk]);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DP hbar_XXZ (DP lambda, int n, int par, DP* si_n_anis_over_2)
|
||||
{
|
||||
DP result = 0.0;
|
||||
|
||||
if (par == 1) result = si_n_anis_over_2[2*n]/(pow(sinh(lambda), 2.0) + pow(si_n_anis_over_2[n], 2.0));
|
||||
|
||||
else if (par == -1) result = si_n_anis_over_2[2*n]/(-pow(cosh(lambda), 2.0) + pow(si_n_anis_over_2[n], 2.0));
|
||||
|
||||
else JSCerror("Faulty parity in hbar_XXZ.");
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DP ddlambda_Theta_XXZ (DP lambda, int nj, int nk, int parj, int park, DP* si_n_anis_over_2)
|
||||
{
|
||||
DP result = (nj == nk) ? 0.0 : hbar_XXZ(lambda, fabs(nj - nk), parj*park, si_n_anis_over_2);
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * hbar_XXZ(lambda, fabs(nj - nk) + 2*a, parj*park, si_n_anis_over_2);
|
||||
|
||||
result += hbar_XXZ(lambda, nj + nk, parj*park, si_n_anis_over_2);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
XXZ_Bethe_State Add_Particle_at_Center (const XXZ_Bethe_State& RefState)
|
||||
{
|
||||
if (2*RefState.base.Mdown == RefState.chain.Nsites)
|
||||
JSCerror("Trying to add a down spin to a zero-magnetized chain in Add_Particle_at_Center.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] + 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXZ_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Add a quantum number in middle (explicitly: to right of index M[0]/2)
|
||||
// and shift quantum numbers by half-integer away from added one:
|
||||
ReturnState.Ix2[0][RefState.base.Nrap[0]/2] = RefState.Ix2[0][RefState.base.Nrap[0]/2] - 1;
|
||||
for (int i = 0; i < RefState.base.Nrap[0] + 1; ++i)
|
||||
ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] = RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
|
||||
XXZ_Bethe_State Remove_Particle_at_Center (const XXZ_Bethe_State& RefState)
|
||||
{
|
||||
if (RefState.base.Nrap[0] == 0)
|
||||
JSCerror("Trying to remove a down spin in an empty Nrap[0] state.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] - 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXZ_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Remove midmost and shift quantum numbers by half-integer towards removed one:
|
||||
for (int i = 0; i < RefState.base.Nrap[0]-1; ++i)
|
||||
ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,814 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/XXZ_gpd_Bethe_State.cc
|
||||
|
||||
Purpose: Defines all functions for XXZ_gpd_Bethe_State
|
||||
|
||||
******************************************************************/
|
||||
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// Function prototypes
|
||||
|
||||
inline DP fbar_XXZ_gpd (DP lambda, int par, DP tanhnetaover2);
|
||||
DP Theta_XXZ_gpd (DP lambda, int nj, int nk, DP* tanhnetaover2);
|
||||
DP hbar_XXZ_gpd (DP lambda, int n, DP* si_n_anis_over_2);
|
||||
DP ddlambda_Theta_XXZ_gpd (DP lambda, int nj, int nk, DP* si_n_anis_over_2);
|
||||
|
||||
|
||||
//***************************************************************************************************
|
||||
|
||||
// Function definitions: class XXZ_gpd_Bethe_State
|
||||
|
||||
XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State ()
|
||||
: Heis_Bethe_State(), sinlambda(Lambda(chain, 1)), coslambda(Lambda(chain, 1)), tanlambda(Lambda(chain, 1))
|
||||
{};
|
||||
|
||||
XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const XXZ_gpd_Bethe_State& RefState) // copy constructor
|
||||
: Heis_Bethe_State(RefState),
|
||||
sinlambda(Lambda(RefState.chain, RefState.base)), coslambda(Lambda(RefState.chain, RefState.base)),
|
||||
tanlambda(Lambda(RefState.chain, RefState.base))
|
||||
{
|
||||
// copy arrays into new ones
|
||||
|
||||
for (int j = 0; j < RefState.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < RefState.base[j]; ++j) {
|
||||
sinlambda[j][alpha] = RefState.sinlambda[j][alpha];
|
||||
coslambda[j][alpha] = RefState.coslambda[j][alpha];
|
||||
tanlambda[j][alpha] = RefState.tanlambda[j][alpha];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, int M)
|
||||
: Heis_Bethe_State(RefChain, M),
|
||||
sinlambda(Lambda(RefChain, M)), coslambda(Lambda(RefChain, M)), tanlambda(Lambda(RefChain, M))
|
||||
{
|
||||
if (RefChain.Delta <= 1.0) JSCerror("Delta too low in XXZ_gpd_Bethe_State constructor");
|
||||
}
|
||||
|
||||
XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase)
|
||||
: Heis_Bethe_State(RefChain, RefBase),
|
||||
sinlambda(Lambda(RefChain, RefBase)), coslambda(Lambda(RefChain, RefBase)),
|
||||
tanlambda(Lambda(RefChain, RefBase))
|
||||
{
|
||||
if (RefChain.Delta <= 1.0) JSCerror("Delta too low in XXZ_gpd_Bethe_State constructor");
|
||||
}
|
||||
/*
|
||||
XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
|
||||
: Heis_Bethe_State(RefChain, base_id_ref, type_id_ref),
|
||||
sinlambda(Lambda(chain, base)), coslambda(Lambda(chain, base)), tanlambda(Lambda(chain, base))
|
||||
{
|
||||
if (RefChain.Delta <= 1.0) JSCerror("Delta too low in XXZ_gpd_Bethe_State constructor");
|
||||
}
|
||||
*/
|
||||
XXZ_gpd_Bethe_State& XXZ_gpd_Bethe_State::operator= (const XXZ_gpd_Bethe_State& RefState)
|
||||
{
|
||||
if (this != &RefState) {
|
||||
chain = RefState.chain;
|
||||
base = RefState.base;
|
||||
//offsets = RefState.offsets;
|
||||
Ix2 = RefState.Ix2;
|
||||
lambda = RefState.lambda;
|
||||
BE = RefState.BE;
|
||||
diffsq = RefState.diffsq;
|
||||
conv = RefState.conv;
|
||||
iter = RefState.iter;
|
||||
iter_Newton = RefState.iter_Newton;
|
||||
E = RefState.E;
|
||||
iK = RefState.iK;
|
||||
K = RefState.K;
|
||||
lnnorm = RefState.lnnorm;
|
||||
//base_id = RefState.base_id;
|
||||
//type_id = RefState.type_id;
|
||||
//id = RefState.id;
|
||||
//maxid = RefState.maxid;
|
||||
//nparticles = RefState.nparticles;
|
||||
label = RefState.label;
|
||||
|
||||
sinlambda = RefState.sinlambda;
|
||||
coslambda = RefState.coslambda;
|
||||
tanlambda = RefState.tanlambda;
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
void XXZ_gpd_Bethe_State::Set_Free_lambdas()
|
||||
{
|
||||
// Sets all the rapidities to the solutions of the BAEs without scattering terms
|
||||
|
||||
for (int i = 0; i < chain.Nstrings; ++i) {
|
||||
|
||||
for (int alpha = 0; alpha < base[i]; ++alpha) {
|
||||
|
||||
lambda[i][alpha] = atan((tanh(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_sinlambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) sinlambda[j][alpha] = sin(lambda[j][alpha]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_coslambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) coslambda[j][alpha] = cos(lambda[j][alpha]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_tanlambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
tanlambda[j][alpha] = tan(lambda[j][alpha]);
|
||||
//if (lambda[j][alpha] > 0.5*PI) cout << "Rapidity higher than 0.5*PI: j = " << j << "\talpha = " << alpha << "\trap = " << lambda[j][alpha] << "\ttan = " << tanlambda[j][alpha] << endl;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool XXZ_gpd_Bethe_State::Check_Admissibility(char option)
|
||||
{
|
||||
// This function checks the admissibility of the Ix2's of a state:
|
||||
// returns false if there are higher strings with Ix2 = 0, a totally symmetric distribution of I's at each level,
|
||||
// and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE.
|
||||
|
||||
bool answer = true;
|
||||
Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
|
||||
|
||||
/*
|
||||
Vect<bool> min_Ix2_max_busy(false, chain.Nstrings);
|
||||
Vect<bool> plus_Ix2_max_busy(false, chain.Nstrings);
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
if (Ix2[j][alpha] == -base.Ix2_max[j]) min_Ix2_max_busy[j] = true;
|
||||
if (Ix2[j][alpha] == base.Ix2_max[j]) plus_Ix2_max_busy[j] = true;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
// State is not admissible if this is false: -N/2 + 1 \leq \sum I^j_{\alpha} \leq N
|
||||
int sum_all_Ix2 = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum_all_Ix2 += Ix2[j][alpha];
|
||||
}
|
||||
if (sum_all_Ix2 > chain.Nsites || sum_all_Ix2 <= -chain.Nsites) {
|
||||
cout << "\tSum Ix2 out of fundamental interval: sum_all_Ix2 = " << sum_all_Ix2 << "\tfor N = " << chain.Nsites << endl;
|
||||
return(false);
|
||||
}
|
||||
*/
|
||||
//Deactivated 2014 06 11, put in Heis_Form_Factor_Entry.cc
|
||||
/*
|
||||
// State is not admissible if I_max > 1/2 (N - \sum_k t_{jk} M_k) or I_min < -1/2 (N - sum_k...) + 1 at any level:
|
||||
int sum1 = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
sum1 = 0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
sum1 += base[k] * (2 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1 : 0));
|
||||
}
|
||||
// Define limits...
|
||||
//if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1;
|
||||
|
||||
// This almost does it: only missing are the states with one on -PI/2 and one on PI/2
|
||||
if (base[j] >= 1 && (Ix2[j][0] <= -(chain.Nsites - sum1) ||
|
||||
(Ix2[j][base[j] - 1] - Ix2[j][0]) > 2*(chain.Nsites - sum1))) {
|
||||
//cout << "\tAn Ix2 is out of interval at level " << j << endl;
|
||||
//cout << Ix2[j][base[j] - 1] << "\t" << Ix2[j][0] << "\t" << chain.Nsites << "\t" << sum1 << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// State is not admissible if both a min_ and plus_Ix2_max are busy simultaneously:
|
||||
bool is_a_min_Ix2_max_busy = false;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) if (min_Ix2_max_busy[j]) is_a_min_Ix2_max_busy = true;
|
||||
bool is_a_plus_Ix2_max_busy = false;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) if (plus_Ix2_max_busy[j]) is_a_plus_Ix2_max_busy = true;
|
||||
*/
|
||||
/*
|
||||
// State is not admissible if all min_Ix2_max are busy simultaneously:
|
||||
bool any_min_Ix2_max_free = false;
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
if (base[j] > 0 && !min_Ix2_max_busy[j]) any_min_Ix2_max_free = true;
|
||||
if (!any_min_Ix2_max_free) return(false);
|
||||
*/
|
||||
/*
|
||||
// State is not admissible if -Ix2_max, -Ix2_max + 2, ..., -Ix2_max + 2*(Str_L - 1) are busy:
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
if (base[j] > 0 && Ix2[j][0] <= -base.Ix2_max[j] + 2*(chain.Str_L[j] - 1))
|
||||
return(false);
|
||||
// Almost correct with above !
|
||||
// State is not admissible if Ix2_max - 2, ..., Ix2_max - 2*(Str_L - 2) are busy (NB: one slot more than on left):
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
if (base[j] > 0 && Ix2[j][base[j] - 1] >= base.Ix2_max[j] - 2*(chain.Str_L[j] - 2))
|
||||
return(false);
|
||||
*/
|
||||
|
||||
// Check that at all at least doubly occupied levels, the difference between max and min quantum numbers
|
||||
// is strictly smaller than 2*Ix2_max - 2, so that lambda_max - lambda_min < PI at each level:
|
||||
//for (int j = 0; j < chain.Nstrings; ++j)
|
||||
//if (base[j] >= 2 && Ix2[j][base[j] - 1] - Ix2[j][0] >= 2* base.Ix2_max[j] - 2) answer = false;
|
||||
|
||||
//if (is_a_min_Ix2_max_busy && is_a_plus_Ix2_max_busy) return(false);
|
||||
|
||||
bool higher_string_on_zero = false;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
// The following line puts answer to true if there is at least one higher string with zero Ix2
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] > 2) /*&& !(chain.Str_L[j] % 2)*/)
|
||||
higher_string_on_zero = true;
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
|
||||
// NOTE: if base[j] == 0, Zero_at_level[j] remains false.
|
||||
}
|
||||
|
||||
bool symmetric_state = (*this).Check_Symmetry();
|
||||
|
||||
bool string_coincidence = false;
|
||||
// Checks that we have strings of equal length modulo 2 and same parity with Ix2 == 0, so equal rapidities, and inadmissibility
|
||||
for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
|
||||
for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
|
||||
if (Zero_at_level[j1] && Zero_at_level[j2] && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
|
||||
string_coincidence = true;
|
||||
}
|
||||
|
||||
//bool onep_onem_on_zero = false;
|
||||
//if (option == 'm' || option == 'p') { // for Smin, we also exclude symmetric states with 1+ and 1- strings on zero
|
||||
//if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
|
||||
//}
|
||||
|
||||
//cout << min_Ix2_max_busy << "\t" << symmetric_state << "\t" << higher_string_on_zero << "\t" << string_coincidence << "\t" << onep_onem_on_zero << endl;
|
||||
|
||||
//answer = !((symmetric_state && (higher_string_on_zero || string_coincidence || onep_onem_on_zero)));
|
||||
answer = !(symmetric_state && (higher_string_on_zero || string_coincidence));
|
||||
|
||||
// Explicitly exclude state with min_Ix2_max_busy && iK == 0
|
||||
//Compute_Momentum();
|
||||
//answer = !((min_Ix2_max_busy && iK == 0) || (symmetric_state && (higher_string_on_zero || string_coincidence || onep_onem_on_zero)));
|
||||
|
||||
// Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
|
||||
|
||||
if (!answer) {
|
||||
E = 0.0;
|
||||
K = 0.0;
|
||||
conv = 0;
|
||||
iter = 0;
|
||||
iter_Newton = 0;
|
||||
lnnorm = -100.0;
|
||||
}
|
||||
|
||||
return(answer); // answer == true: nothing wrong with this Ix2_config
|
||||
}
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_BE (int j, int alpha)
|
||||
{
|
||||
// Fills in the BE members with the value of the Bethe equations.
|
||||
|
||||
tanlambda[j][alpha] = tan(lambda[j][alpha]);
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) {
|
||||
sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta])
|
||||
* chain.ta_n_anis_over_2[2]))
|
||||
+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
|
||||
+ PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0))
|
||||
* floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = 2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
+ PI * floor(0.5 + lambda[j][alpha]/PI))
|
||||
- (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
}
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_BE ()
|
||||
{
|
||||
// Fills in the BE members with the value of the Bethe equations.
|
||||
|
||||
(*this).Compute_tanlambda();
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) {
|
||||
sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta])
|
||||
* chain.ta_n_anis_over_2[2]))
|
||||
+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
|
||||
+ PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0))
|
||||
* floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = 2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
+ PI * floor(0.5 + lambda[j][alpha]/PI))
|
||||
- (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
}
|
||||
}
|
||||
|
||||
DP XXZ_gpd_Bethe_State::Iterate_BAE (int j, int alpha)
|
||||
{
|
||||
// Returns a new iteration value for lambda[j][alpha] given tanlambda[][] and BE[][]
|
||||
// Assumes that tanlambda[][] and BE[][] have been computed.
|
||||
|
||||
DP arg0 = 0.5 * (2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
+ PI * floor(0.5 + lambda[j][alpha]/PI)) - BE[j][alpha]);
|
||||
DP arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(
|
||||
arg0
|
||||
//0.5 *
|
||||
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
|
||||
//(2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
// + PI * floor(0.5 + lambda[j][alpha]/PI)) - BE[j][alpha])
|
||||
);
|
||||
|
||||
return(atan(arg)
|
||||
//+ PI * floor(0.5 + arg0)
|
||||
//0.5 * (Ix2[j][alpha] + sumtheta/PI)/(chain.Nsites)
|
||||
+ PI * floor(0.5 + arg0/PI)
|
||||
);
|
||||
|
||||
}
|
||||
/*
|
||||
void XXZ_gpd_Bethe_State::Iterate_BAE ()
|
||||
{
|
||||
// Recalculates the rapidities by iterating Bethe equations
|
||||
|
||||
Lambda New_lambda(chain, base);
|
||||
DP sumtheta = 0.0;
|
||||
DP arg = 0.0;
|
||||
|
||||
// First, compute the tan of rapidities:
|
||||
(*this).Compute_tanlambda();
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += atan((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta])
|
||||
* chain.ta_n_anis_over_2[2]))
|
||||
+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
|
||||
else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
|
||||
+ PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0))
|
||||
* floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan((PI * 0.5 * Ix2[j][alpha] + 0.5 * sumtheta)/chain.Nsites);
|
||||
|
||||
New_lambda[j][alpha] = atan(arg) + PI * floor(0.5 + (0.5 * Ix2[j][alpha] + 0.5 * sumtheta/PI)/(chain.Nsites));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DP New_diffsq = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
//New_diffsq += pow(tan(New_lambda[j][alpha]) - tanlambda[j][alpha], 2.0);
|
||||
New_diffsq += pow(New_lambda[j][alpha] - lambda[j][alpha], 2.0);
|
||||
lambda[j][alpha] = 1.0 * New_lambda[j][alpha] + 0.0 * lambda[j][alpha];
|
||||
}
|
||||
}
|
||||
|
||||
diffsq = New_diffsq;
|
||||
iter++;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void XXZ_gpd_Bethe_State::Iterate_BAE_Newton ()
|
||||
{
|
||||
// does one step of a Newton method on the rapidities...
|
||||
|
||||
Vect_DP RHSBAE (0.0, base.Nraptot); // contains RHS of BAEs
|
||||
Vect_CX dlambda (0.0, base.Nraptot); // contains delta lambda computed from Newton's method
|
||||
SQMat_CX Gaudin (0.0, base.Nraptot);
|
||||
Vect_INT indx (base.Nraptot);
|
||||
DP sumtheta = 0.0;
|
||||
DP arg = 0.0;
|
||||
DP fn_arg = 0.0;
|
||||
DP olddiffsq = diffsq;
|
||||
|
||||
// Compute the RHS of the BAEs:
|
||||
|
||||
int index = 0;
|
||||
|
||||
(*this).Compute_tanlambda();
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) {
|
||||
sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta])
|
||||
* chain.ta_n_anis_over_2[2]))
|
||||
+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
|
||||
+ PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0))
|
||||
* floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
RHSBAE[index] = chain.Nsites * 2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
+ PI * floor(0.5 + lambda[j][alpha]/PI))
|
||||
// )
|
||||
- sumtheta - PI*Ix2[j][alpha];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
(*this).Build_Reduced_Gaudin_Matrix (Gaudin);
|
||||
|
||||
for (int i = 0; i < base.Nraptot; ++i) dlambda[i] = - RHSBAE[i];
|
||||
|
||||
DP d;
|
||||
ludcmp_CX (Gaudin, indx, d);
|
||||
lubksb_CX (Gaudin, indx, dlambda);
|
||||
|
||||
diffsq = 0.0;
|
||||
// for (int i = 0; i < base.Nraptot; ++i) diffsq += norm(dlambda[i]);
|
||||
int ctr = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
diffsq += norm(tan(lambda[j][alpha] + dlambda[ctr]) - tanlambda[j][alpha]);
|
||||
// cout << "lambda = " << lambda[j][alpha] << "\tdlambda = " << dlambda[ctr] << endl;
|
||||
ctr++;
|
||||
}
|
||||
}
|
||||
|
||||
// if we've converged, calculate the norm here, since the work has been done...
|
||||
|
||||
if (diffsq < chain.prec) {
|
||||
lnnorm = 0.0;
|
||||
for (int j = 0; j < base.Nraptot; j++) lnnorm += log(abs(Gaudin[j][j]));
|
||||
}
|
||||
|
||||
index = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
lambda[j][alpha] += real(dlambda[index]);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
iter_Newton++;
|
||||
|
||||
// cout << "iter_N = " << iter_Newton << "\t" << diffsq << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
bool XXZ_gpd_Bethe_State::Check_Rapidities()
|
||||
{
|
||||
bool nonan = true;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if (nonan) nonan = ((!is_nan(lambda[j][alpha]))
|
||||
//&& (lambda[j][alpha] > -0.5*PI*chain.Str_L[j])
|
||||
//&& (lambda[j][alpha] <= 0.5*PI*chain.Str_L[j])
|
||||
);
|
||||
|
||||
bool all_within_pi_interval = true;
|
||||
DP min_lambda = 10.0;
|
||||
DP max_lambda = -10.0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
if (lambda[j][alpha] < min_lambda) min_lambda = lambda[j][alpha];
|
||||
if (lambda[j][alpha] > max_lambda) max_lambda = lambda[j][alpha];
|
||||
}
|
||||
|
||||
//all_within_pi_interval = (fabs(max_lambda - min_lambda) < PI - 0.0 * 1.0e-12);
|
||||
// Use pi interval, but centered on 0:
|
||||
all_within_pi_interval = max_lambda < 0.5* PI + 1.0e-8 && min_lambda > -0.5* PI - 1.0e-8;
|
||||
//nonan *= all_within_pi_interval;
|
||||
|
||||
return nonan;
|
||||
}
|
||||
|
||||
DP XXZ_gpd_Bethe_State::String_delta ()
|
||||
{
|
||||
// Computes the sum of absolute value of \delta^{a, a+1} in string hypothesis, for a given bethe eigenstate
|
||||
|
||||
DP delta = 0.0;
|
||||
|
||||
int occupied_strings = 0;
|
||||
for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
|
||||
|
||||
//if ((*this).conv == 0) delta = 1.0;
|
||||
|
||||
if (occupied_strings == 0) delta = 0.0;
|
||||
|
||||
else {
|
||||
|
||||
Vect_DP ln_deltadiff(0.0, 1000); // contains ln |delta^{a, a+1}|
|
||||
Vect_DP deltadiff(0.0, 1000); // contains |delta^{a, a+1}|
|
||||
|
||||
complex<DP> log_BAE_reg = 0.0;
|
||||
|
||||
for (int j = 0; j < (*this).chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < (*this).base[j]; ++alpha) {
|
||||
|
||||
ln_deltadiff = 0.0;
|
||||
|
||||
for (int a = 1; a <= (*this).chain.Str_L[j]; ++a) {
|
||||
|
||||
if ((*this).chain.Str_L[j] > 1) { // else the BAE are already 1
|
||||
|
||||
log_BAE_reg = DP((*this).chain.Nsites) * log(sin((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis
|
||||
* ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0))
|
||||
/sin((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int k = 0; k < (*this).chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < (*this).base[k]; ++beta)
|
||||
for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
|
||||
if ((j != k) || (alpha != beta) || (a != b - 1))
|
||||
|
||||
log_BAE_reg += log(sin(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a ))
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ))
|
||||
- II * (*this).chain.anis));
|
||||
|
||||
if ((j != k) || (alpha != beta) || (a != b + 1))
|
||||
|
||||
log_BAE_reg -= log(sin(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a ))
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ))
|
||||
+ II * (*this).chain.anis));
|
||||
}
|
||||
|
||||
// The regular LHS of BAE is now defined. Now sum up the deltas...
|
||||
|
||||
if (a == 1) ln_deltadiff[0] = -real(log_BAE_reg);
|
||||
|
||||
else if (a < (*this).chain.Str_L[j]) ln_deltadiff[a - 1] = ln_deltadiff[a-2] - real(log_BAE_reg);
|
||||
|
||||
else if (a == (*this).chain.Str_L[j]) ln_deltadiff[a-1] = real(log_BAE_reg);
|
||||
|
||||
} // if ((*this).chain.Str_L[j] > 1)
|
||||
|
||||
} // for (int a = 1; ...
|
||||
|
||||
for (int a = 0; a < (*this).chain.Str_L[j]; ++a) {
|
||||
deltadiff[a] = ln_deltadiff[a] != 0.0 ? exp(ln_deltadiff[a]) : 0.0;
|
||||
delta += fabs(deltadiff[a]);
|
||||
}
|
||||
|
||||
} // alpha sum
|
||||
} // j sum
|
||||
|
||||
if (is_nan(delta)) delta = 1.0; // sentinel
|
||||
|
||||
} // else
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_Energy ()
|
||||
{
|
||||
DP sum = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum += sinh(chain.Str_L[j] * chain.anis) / (cos(2.0 * lambda[j][alpha]) - cosh(chain.Str_L[j] * chain.anis));
|
||||
}
|
||||
}
|
||||
|
||||
sum *= chain.J * sinh(chain.anis);
|
||||
|
||||
E = sum;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
void XXZ_gpd_Bethe_State::Compute_Momentum ()
|
||||
{
|
||||
int sum_Ix2 = 0;
|
||||
DP sum_M = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
sum_M += base[j];
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum_Ix2 += Ix2[j][alpha];
|
||||
}
|
||||
}
|
||||
|
||||
iK = (chain.Nsites/2) * int(sum_M) - (sum_Ix2/2);
|
||||
|
||||
while (iK >= chain.Nsites) iK -= chain.Nsites;
|
||||
while (iK < 0) iK += chain.Nsites;
|
||||
|
||||
K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
|
||||
|
||||
while (K >= 2.0*PI) K -= 2.0*PI;
|
||||
while (K < 0.0) K += 2.0*PI;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
void XXZ_gpd_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
|
||||
{
|
||||
|
||||
if (Gaudin_Red.size() != base.Nraptot) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
|
||||
int index_jalpha;
|
||||
int index_kbeta;
|
||||
|
||||
DP sum_hbar_XXZ = 0.0;
|
||||
|
||||
DP sinhetasq = pow(sinh(chain.anis), 2.0);
|
||||
|
||||
(*this).Compute_sinlambda();
|
||||
(*this).Compute_coslambda();
|
||||
|
||||
index_jalpha = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
index_kbeta = 0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta) {
|
||||
|
||||
if ((j == k) && (alpha == beta)) {
|
||||
|
||||
sum_hbar_XXZ = 0.0;
|
||||
|
||||
for (int kp = 0; kp < chain.Nstrings; ++kp) {
|
||||
for (int betap = 0; betap < base[kp]; ++betap) {
|
||||
if (!((j == kp) && (alpha == betap)))
|
||||
sum_hbar_XXZ
|
||||
+= ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp],
|
||||
chain.si_n_anis_over_2);
|
||||
}
|
||||
}
|
||||
|
||||
Gaudin_Red[index_jalpha][index_kbeta]
|
||||
= complex<DP> ( chain.Nsites * hbar_XXZ_gpd (lambda[j][alpha], chain.Str_L[j], chain.si_n_anis_over_2) - sum_hbar_XXZ);
|
||||
}
|
||||
|
||||
else {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
Gaudin_Red[index_jalpha][index_kbeta] =
|
||||
complex<DP> (chain.si_n_anis_over_2[4]/(pow(sinlambda[j][alpha] * coslambda[k][beta]
|
||||
- coslambda[j][alpha] * sinlambda[k][beta], 2.0) + sinhetasq));
|
||||
else
|
||||
Gaudin_Red[index_jalpha][index_kbeta] = complex<DP> (ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j],
|
||||
chain.Str_L[k], chain.si_n_anis_over_2));
|
||||
}
|
||||
index_kbeta++;
|
||||
}
|
||||
}
|
||||
index_jalpha++;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
|
||||
// non-member functions
|
||||
|
||||
inline DP fbar_XXZ_gpd (DP tanlambda, DP tanhnetaover2)
|
||||
{
|
||||
return (2.0 * atan(tanlambda/tanhnetaover2));
|
||||
}
|
||||
|
||||
DP Theta_XXZ_gpd (DP tanlambda, int nj, int nk, DP* tanhnetaover2)
|
||||
{
|
||||
DP result;
|
||||
|
||||
if ((nj == 1) && (nk == 1)) result = fbar_XXZ_gpd(tanlambda, tanhnetaover2[2]);
|
||||
|
||||
else {
|
||||
|
||||
result = (nj == nk) ? 0.0 : fbar_XXZ_gpd(tanlambda, tanhnetaover2[fabs(nj - nk)]);
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * fbar_XXZ_gpd(tanlambda, tanhnetaover2[fabs(nj - nk) + 2*a]);
|
||||
|
||||
result += fbar_XXZ_gpd(tanlambda, tanhnetaover2[nj + nk]);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DP hbar_XXZ_gpd (DP lambda, int n, DP* si_n_anis_over_2)
|
||||
{
|
||||
return (si_n_anis_over_2[2*n]/(pow(sin(lambda), 2.0) + pow(si_n_anis_over_2[n], 2.0)));
|
||||
}
|
||||
|
||||
DP ddlambda_Theta_XXZ_gpd (DP lambda, int nj, int nk, DP* si_n_anis_over_2)
|
||||
{
|
||||
DP result = (nj == nk) ? 0.0 : hbar_XXZ_gpd(lambda, fabs(nj - nk), si_n_anis_over_2);
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * hbar_XXZ_gpd(lambda, fabs(nj - nk) + 2*a, si_n_anis_over_2);
|
||||
|
||||
result += hbar_XXZ_gpd(lambda, nj + nk, si_n_anis_over_2);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
XXZ_gpd_Bethe_State Add_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState)
|
||||
{
|
||||
if (2*RefState.base.Mdown == RefState.chain.Nsites)
|
||||
JSCerror("Trying to add a down spin to a zero-magnetized chain in Add_Particle_at_Center.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] + 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXZ_gpd_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Add a quantum number in middle (explicitly: to right of index M[0]/2)
|
||||
// and shift quantum numbers by half-integer away from added one:
|
||||
ReturnState.Ix2[0][RefState.base.Nrap[0]/2] = RefState.Ix2[0][RefState.base.Nrap[0]/2] - 1;
|
||||
for (int i = 0; i < RefState.base.Nrap[0] + 1; ++i)
|
||||
ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] = RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
|
||||
XXZ_gpd_Bethe_State Remove_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState)
|
||||
{
|
||||
if (RefState.base.Nrap[0] == 0)
|
||||
JSCerror("Trying to remove a down spin in an empty Nrap[0] state.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] - 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXZ_gpd_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Remove midmost and shift quantum numbers by half-integer towards removed one:
|
||||
for (int i = 0; i < RefState.base.Nrap[0]-1; ++i)
|
||||
ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,253 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Overlap (XXX_Bethe_State& A, XXX_Bethe_State& B)
|
||||
{
|
||||
// This function returns the overlap of states A and B.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// IMPORTANT ASSUMPTIONS:
|
||||
// - State B is an eigenstate of the model on which the overlap measure is defined
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) return(complex<DP>(-300.0)); // overlap vanishes
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
//complex<DP> ln_prod1 = 0.0;
|
||||
//complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
/*
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
*/
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
|
||||
|
||||
// ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
// ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
|
||||
|
||||
// Now proceed to build the Hm2P matrix
|
||||
|
||||
SQMat_CX Hm2P(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
//complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
//complex<DP> two_over_A_lambda_sq_plus_1over2sq;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
//two_over_A_lambda_sq_plus_1over2sq = 2.0/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
|
||||
// (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
//Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (B.chain.Nsites));
|
||||
Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (A.chain.Nsites)); // careful !
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
|
||||
//- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
|
||||
;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
//sum2 = 0.0;
|
||||
|
||||
//for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1))); // include all string contributions F_B_0 in this term
|
||||
|
||||
//Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq);
|
||||
Hm2P[index_a][index_b] = prod_num * sum1;
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
//cout << "Matrix: " << endl;
|
||||
//Hm2P.Print();
|
||||
|
||||
complex<DP> det = lndet_LU_CX_dstry(Hm2P);
|
||||
|
||||
/*
|
||||
complex<DP> ln_form_factor_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
// + 2.0 * real(lndet_LU_CX_dstry(Hm2P))
|
||||
+ 2.0 * det
|
||||
- A.lnnorm - B.lnnorm;
|
||||
|
||||
//cout << "ln_SZ: " << endl << ln_prod1 << "\t" << -ln_prod2 << "\t" << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
|
||||
// << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
|
||||
|
||||
return(ln_form_factor_sq);
|
||||
*/
|
||||
complex<DP> ln_overlap = 0.5 * (-ln_prod3 + ln_prod4) + det - 0.5 * (A.lnnorm + B.lnnorm);
|
||||
|
||||
cout << "ln_overlap: " << endl << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
|
||||
<< "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
|
||||
|
||||
return(ln_overlap);
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,239 @@
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Smin_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^- operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states are compatible
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Smin matrix element.");
|
||||
|
||||
// Check that A and B are Mdown-compatible:
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown + 1) JSCerror("Incompatible Mdown between the two states in Smin matrix element!");
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
complex<DP> ln_FB0, ln_FG0, ln_FG2;
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
//re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
//im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
ln_FB0 = ln_Fn_F(B, j, alpha, 0);
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_FB0);
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_FB0);
|
||||
//re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
//im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
ln_FG0 = ln_Fn_G(A, B, j, alpha, 0);
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_FG0);
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_FG0);
|
||||
//re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
//im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
ln_FG2 = ln_Fn_G(A, B, j, alpha, 2);
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_FG2);
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_FG2);
|
||||
}
|
||||
}
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);
|
||||
|
||||
// ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
// ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
|
||||
|
||||
// Now proceed to build the Hm matrix
|
||||
|
||||
SQMat_CX Hm(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> one_over_A_lambda_sq_plus_1over2sq;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
one_over_A_lambda_sq_plus_1over2sq = 1.0/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
|
||||
(A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] + II * 0.5) /(B.lambda[k][beta] - II * 0.5), complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
|
||||
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
/*
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
*/
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)));
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm[index_a][index_b] = prod_num * sum1;
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements Hm[a][M]
|
||||
|
||||
Hm[index_a][B.base.Mdown] = one_over_A_lambda_sq_plus_1over2sq;
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
+ 2.0 * real(lndet_LU_CX_dstry(Hm)) - A.lnnorm - B.lnnorm;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,328 @@
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
int arg = 0;
|
||||
int absarg = 0;
|
||||
int par_comb_1, par_comb_2;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
|
||||
par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
|
||||
par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
|
||||
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b))) {
|
||||
|
||||
arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
absarg = abs(arg);
|
||||
/*
|
||||
prod_temp *= 0.5 * //done later...
|
||||
((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
+ B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
|
||||
*/
|
||||
|
||||
prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
|
||||
}
|
||||
|
||||
if (counter++ > 100) { // we do at most 100 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXZ_Bethe_State& A, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
int arg = 0;
|
||||
int absarg = 0;
|
||||
int par_comb_1, par_comb_2;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
|
||||
par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
|
||||
par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
|
||||
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
absarg = abs(arg);
|
||||
/*
|
||||
prod_temp *= 0.5 * //done later...
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) );
|
||||
*/
|
||||
prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
|
||||
|
||||
if (counter++ > 100) { // we do at most 100 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXZ_Bethe_State& A, int j, int alpha, int a, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
int absarg1 = abs(arg1);
|
||||
int arg2 = arg1 + 2;
|
||||
int absarg2 = abs(arg2);
|
||||
|
||||
return(4.0/(
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
|
||||
*
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXZ_Bethe_State& A, int j, int alpha, int a, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
+ 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k])))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Smin_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^- operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states are compatible
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXZ_Chains in Smin matrix element.");
|
||||
|
||||
// Check that A and B are Mdown-compatible:
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown + 1) {
|
||||
cout << "A.base.Mdown = " << A.base.Mdown << "\tB.base.Mdown = " << B.base.Mdown << endl;
|
||||
cout << "A: " << A << endl << "B: " << B << endl;
|
||||
JSCerror("Incompatible Mdown between the two states in Smin matrix element!");
|
||||
}
|
||||
|
||||
// Compute the sinh and cosh of rapidities
|
||||
|
||||
A.Compute_sinhlambda();
|
||||
A.Compute_coshlambda();
|
||||
B.Compute_sinhlambda();
|
||||
B.Compute_coshlambda();
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[i]))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
DP logabssinzeta = log(abs(sin(A.chain.anis)));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1); // assume only one-strings here
|
||||
|
||||
ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
|
||||
|
||||
// Now proceed to build the Hm matrix
|
||||
|
||||
SQMat_CX Hm(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
|
||||
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
one_over_A_sinhlambda_sq_plus_sinzetaover2sq = 1.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
* (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
+ pow(sin(0.5*A.chain.anis), 2.0));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
|
||||
|
||||
Prod_powerN = pow( B.chain.par[k] == 1 ?
|
||||
(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
:
|
||||
(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
, complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
|
||||
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
/*
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
*/
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinzeta);
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm[index_a][index_b] = prod_num * sum1;
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements Hm[a][M]
|
||||
|
||||
Hm[index_a][B.base.Mdown] = one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
+ 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinzeta - A.lnnorm - B.lnnorm;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,303 @@
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
/*
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(-II * sin(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.eta * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))));
|
||||
*/
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b))) {
|
||||
|
||||
// arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// absarg = abs(arg);
|
||||
|
||||
prod_temp *= -II * (B.sinlambda[j][alpha] * B.coslambda[k][beta] - B.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(B.coslambda[j][alpha] * B.coslambda[k][beta] + B.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (counter++ > 10) { // we do at most 10 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
// return(ans);
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
/*
|
||||
prod_temp *= -II * sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.eta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
*/
|
||||
|
||||
// arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// absarg = abs(arg);
|
||||
|
||||
prod_temp *= -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
|
||||
if (counter++ > 25) { // we do at most 25 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
}}}
|
||||
|
||||
// return(ans);
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXZ_gpd_Bethe_State& A, int j, int alpha, int a, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
/*
|
||||
return(-1.0/(sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)))));
|
||||
*/
|
||||
|
||||
// int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// int absarg1 = abs(arg1);
|
||||
// int arg2 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b - 1);
|
||||
// int arg2 = arg1 + 2;
|
||||
// int absarg2 = abs(arg2);
|
||||
|
||||
return(1.0/(( -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))) *
|
||||
(-II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))))));
|
||||
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXZ_gpd_Bethe_State& A, int j, int alpha, int a, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
/*
|
||||
complex<DP> ans = -II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))));
|
||||
|
||||
return (ans * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
*/
|
||||
return (-II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Smin_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^- operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXZ_gpd_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXZ_gpd_Chains in Smin matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown + 1) JSCerror("Incompatible Mdown between the two states in Smin matrix element!");
|
||||
|
||||
// Compute the sin and cos of rapidities
|
||||
|
||||
A.Compute_sinlambda();
|
||||
A.Compute_coslambda();
|
||||
B.Compute_sinlambda();
|
||||
B.Compute_coslambda();
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(sin(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(sin(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(sin(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
// one_over_A_sinlambda_sq_plus_sinhetaover2sq[j][alpha] = 1.0/(pow(A.sinlambda[j][alpha], 2.0) + pow(sinh(0.5*A.chain.anis), 2.0));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
DP logabssinheta = log(abs(sinh(A.chain.anis)));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);
|
||||
|
||||
ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
ln_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis)));
|
||||
|
||||
// Now proceed to build the Hm matrix
|
||||
|
||||
SQMat_CX Hm(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> one_over_A_sinlambda_sq_plus_sinhetaover2sq = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
one_over_A_sinlambda_sq_plus_sinhetaover2sq = -1.0/((sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
|
||||
+ 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a))) *
|
||||
(sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
|
||||
+ 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)))
|
||||
+ pow(sinh(0.5*A.chain.anis), 2.0));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
|
||||
|
||||
Prod_powerN = pow((B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1]),
|
||||
complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
/*
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
*/
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinheta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinheta);
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm[index_a][index_b] = prod_num * sum1;
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements Hm[a][M]
|
||||
|
||||
Hm[index_a][B.base.Mdown] = one_over_A_sinlambda_sq_plus_sinhetaover2sq;
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
+ 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinheta - A.lnnorm - B.lnnorm;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,307 @@
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
inline complex<DP> phi(complex<DP> x){return x;}
|
||||
inline complex<DP> a(complex<DP> x){return 1;}
|
||||
inline complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta){ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
|
||||
inline complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
|
||||
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
|
||||
complex<DP> ln_Smm_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
|
||||
{
|
||||
const DP Zero_Center_Thres=1.0e-5;
|
||||
const DP real_dev=1.0e-14;
|
||||
const DP Diff_ME_Thres=1.e-6;
|
||||
|
||||
//clock_t start_time_local = clock();
|
||||
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
// A is the reference state.
|
||||
|
||||
// Check that the two states refer to the same XXX_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Smm matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown + 2) JSCerror("Incompatible Mdown between the two states in Smm matrix element!");
|
||||
|
||||
//if(B.String_delta()> HEIS_deltaprec) return(complex<DP>(-300.0)); // DEPRECATED in ++T_9
|
||||
|
||||
|
||||
//if (B.type_id > 999999LL) return(complex<DP>(-300.0));
|
||||
|
||||
// Some convenient arrays
|
||||
complex<DP> eta=-II;
|
||||
complex<DP> ln_prod = complex<DP>(0.0,0.0);
|
||||
complex<DP> result=-300;
|
||||
complex<DP> prev_result=-300;
|
||||
|
||||
XXX_Bethe_State B_origin; B_origin=B;
|
||||
bool zero_string=false;
|
||||
for (int j = 0; j < B_origin.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < B_origin.base.Nrap[j]; ++alpha)
|
||||
if(abs(B_origin.lambda[j][alpha])<Zero_Center_Thres) zero_string=true;
|
||||
|
||||
// Some convenient arrays
|
||||
bool real_dev_conv=false;
|
||||
int dev=-1;
|
||||
while(!real_dev_conv){
|
||||
real_dev_conv=true;
|
||||
|
||||
dev++;
|
||||
//add a delta to the origin of the centered strings
|
||||
if(zero_string){
|
||||
real_dev_conv=false;
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha)
|
||||
if(abs(B_origin.lambda[j][alpha])<Zero_Center_Thres)
|
||||
B.lambda[j][alpha]=real_dev*pow(10.0,dev);
|
||||
}
|
||||
|
||||
prev_result=result;
|
||||
|
||||
|
||||
|
||||
result=log(B.chain.Nsites*1.0);
|
||||
|
||||
int sizeA=0;
|
||||
int sizeB=0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
sizeA+=A.base.Nrap[i]*A.chain.Str_L[i];
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
sizeB+=B.base.Nrap[i]*B.chain.Str_L[i];
|
||||
|
||||
complex<DP>* mu = new complex<DP>[sizeA];
|
||||
complex<DP>* lam = new complex<DP>[sizeB];
|
||||
int index=0;
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
{
|
||||
mu[index]=(A.lambda[i][alpha] + 0.5 * -eta * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
index++;
|
||||
}
|
||||
|
||||
index=0;
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
{
|
||||
lam[index]=(B.lambda[i][alpha] + 0.5 * -eta * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
index++;
|
||||
}
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
result += 2.0*real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4) - A.lnnorm - B.lnnorm;
|
||||
// Define the F ones earlier...
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
complex<DP> Prod_powerN;
|
||||
|
||||
//mu is the ground state!
|
||||
//A -> mu, B -> lam
|
||||
SQMat_CX H(0.0, A.base.Mdown);
|
||||
index_a = 0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
complex<DP> Da;
|
||||
complex<DP> Ca;
|
||||
Da=eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
|
||||
Ca=eta*((mu[index_a]-eta*0.5)+(mu[index_a]+eta*0.5))/pow(((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5)),2.0);
|
||||
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
|
||||
complex<DP> prodplus= complex<DP>(1.0,0.0);
|
||||
complex<DP> prodminus= complex<DP>(1.0,0.0);
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
|
||||
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
|
||||
|
||||
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
|
||||
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] - eta*0.5) /(B.lambda[k][beta] + eta*0.5), complex<DP> (B.chain.Nsites));
|
||||
H[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
// */{
|
||||
|
||||
if (b > 1){
|
||||
H[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)*exp(ln_Fn_G(A,B,k,beta,b-1))*exp(-real(ln_Fn_F(B, k, beta, b - 1)));//.../ prod_l!=k | phi(lam[l]-lam[k]) |
|
||||
}
|
||||
else if (b == 1) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
complex<DP> sum1 = complex<DP>(0.0,0.0);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1]
|
||||
- ln_FunctionF[0] - ln_FunctionF[1]);//sum term when i=0
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); //sum term when i=n
|
||||
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) {
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
}
|
||||
|
||||
H[index_a][index_b] = eta * exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum1 * exp( - real(ln_Fn_F(B, k, beta, b - 1))); //the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements H[a][M] & H[a][M-1]
|
||||
H[index_a][B.base.Mdown]=Da;
|
||||
H[index_a][B.base.Mdown+1]=Ca;
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> logF=lndet_LU_CX_dstry(H);
|
||||
result+=2.0*real(logF);
|
||||
result+=log(2.0)-log((A.chain.Nsites-A.base.Mdown*2+3.0)*((A.chain.Nsites-A.base.Mdown*2+4.0)));
|
||||
if (!(real_dev_conv) && abs(exp(result)-exp(prev_result))<abs( Diff_ME_Thres*exp(result)))
|
||||
real_dev_conv=true;
|
||||
|
||||
if (!(real_dev_conv) && dev >20){
|
||||
result=-300;
|
||||
real_dev_conv=true;
|
||||
}
|
||||
|
||||
delete[] mu;
|
||||
delete[] lam;
|
||||
|
||||
}
|
||||
//return(result);
|
||||
return(0.5 * result); // Return ME, not MEsq
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,247 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Sz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXX_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Sz matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
|
||||
|
||||
//if (A.iK == B.iK && (A.label != B.label))
|
||||
if (A.iK == B.iK && (A.label.compare(B.label) != 0))
|
||||
return(-300.0); // matrix element identically vanishes
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
|
||||
|
||||
// ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
// ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
|
||||
|
||||
// Now proceed to build the Hm2P matrix
|
||||
|
||||
SQMat_CX Hm2P(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> two_over_A_lambda_sq_plus_1over2sq;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
two_over_A_lambda_sq_plus_1over2sq = 2.0/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
|
||||
(A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
|
||||
- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1))); // include all string contributions F_B_0 in this term
|
||||
|
||||
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq);
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
//cout << "Matrix: " << endl;
|
||||
//Hm2P.Print();
|
||||
|
||||
DP det = real(lndet_LU_CX_dstry(Hm2P));
|
||||
|
||||
complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
// + 2.0 * real(lndet_LU_CX_dstry(Hm2P))
|
||||
+ 2.0 * det
|
||||
- A.lnnorm - B.lnnorm;
|
||||
|
||||
//cout << "ln_Sz: " << endl << ln_prod1 << "\t" << -ln_prod2 << "\t" << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
|
||||
// << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,563 @@
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
int arg = 0;
|
||||
int absarg = 0;
|
||||
int par_comb_1, par_comb_2;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
|
||||
par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
|
||||
par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
|
||||
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b))) {
|
||||
|
||||
arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
absarg = abs(arg);
|
||||
/*
|
||||
prod_temp *= 0.5 *
|
||||
((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg)
|
||||
* B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
+ B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
|
||||
*/
|
||||
prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
|
||||
|
||||
}
|
||||
|
||||
if (counter++ > 100) { // we do at most 100 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXZ_Bethe_State& A, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
int arg = 0;
|
||||
int absarg = 0;
|
||||
int par_comb_1, par_comb_2;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
|
||||
par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
|
||||
par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
|
||||
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
absarg = abs(arg);
|
||||
|
||||
/*
|
||||
prod_temp *= 0.5 *
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) );
|
||||
*/
|
||||
prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
|
||||
|
||||
if (counter++ > 100) { // we do at most 100 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXZ_Bethe_State& A, int j, int alpha, int a, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
int absarg1 = abs(arg1);
|
||||
int arg2 = arg1 + 2;
|
||||
int absarg2 = abs(arg2);
|
||||
|
||||
return(4.0/(
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
|
||||
*
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXZ_Bethe_State& A, int j, int alpha, int a, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
+ 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k])))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
|
||||
// Version without phases:
|
||||
complex<DP> ln_Sz_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXZ_Chain
|
||||
|
||||
if (A.chain != B.chain) {
|
||||
JSCerror("Incompatible XXZ_Chains in Sz matrix element.");
|
||||
}
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) {
|
||||
cout << "Bra state: " << endl << A << endl;
|
||||
cout << "Ket state: " << endl << B << endl;
|
||||
cout << A.base.Mdown << "\t" << B.base.Mdown << endl;
|
||||
JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
|
||||
}
|
||||
|
||||
if (A.iK == B.iK && (A.label != B.label))
|
||||
return(-300.0); // matrix element identically vanishes
|
||||
|
||||
// Compute the sinh and cosh of rapidities
|
||||
|
||||
A.Compute_sinhlambda();
|
||||
A.Compute_coshlambda();
|
||||
B.Compute_sinhlambda();
|
||||
B.Compute_coshlambda();
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[i]))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
complex<DP> ln_Fn_F_B_0;
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
ln_Fn_F_B_0 = ln_Fn_F(B, j, alpha, 0);
|
||||
//re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
//im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F_B_0);
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F_B_0);
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
DP logabssinzeta = log(abs(sin(A.chain.anis)));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
|
||||
}
|
||||
|
||||
ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
|
||||
|
||||
// Now proceed to build the Hm2P matrix
|
||||
|
||||
SQMat_CX Hm2P(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> two_over_A_sinhlambda_sq_plus_sinzetaover2sq;
|
||||
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
two_over_A_sinhlambda_sq_plus_sinzetaover2sq = 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
* (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
+ pow(sin(0.5*A.chain.anis), 2.0));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
|
||||
|
||||
Prod_powerN = pow( B.chain.par[k] == 1 ?
|
||||
(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
:
|
||||
(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
, complex<DP> (B.chain.Nsites));
|
||||
|
||||
//cout << "Prod_powerN = " << Prod_powerN << "\t" << abs(Prod_powerN) << endl;
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq
|
||||
* exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinzeta);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logabssinzeta);
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinhlambda_sq_plus_sinzetaover2sq);
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
DP re_ln_det = real(lndet_LU_CX_dstry(Hm2P));
|
||||
|
||||
complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
+ 2.0 * /*real(lndet_LU_CX_dstry(Hm2P))*/ re_ln_det - A.lnnorm - B.lnnorm;
|
||||
|
||||
//cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm
|
||||
//<< "\t" << re_ln_det << "\t" << ln_ME_sq << endl;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
// Version with phases:
|
||||
complex<DP> ln_Sz_ME_with_phase (XXZ_Bethe_State& A, XXZ_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXZ_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXZ_Chains in Sz matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) {
|
||||
cout << "Bra state: " << endl << A << endl;
|
||||
cout << "Ket state: " << endl << B << endl;
|
||||
cout << A.base.Mdown << "\t" << B.base.Mdown << endl;
|
||||
JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
|
||||
}
|
||||
|
||||
if (A.iK == B.iK && (A.label != B.label))
|
||||
return(-300.0); // matrix element identically vanishes
|
||||
|
||||
// Compute the sinh and cosh of rapidities
|
||||
|
||||
A.Compute_sinhlambda();
|
||||
A.Compute_coshlambda();
|
||||
B.Compute_sinhlambda();
|
||||
B.Compute_coshlambda();
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[i])));
|
||||
|
||||
complex<DP> shB;
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(shB = sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
|
||||
//ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
// + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
|
||||
ln_prod2 += log(shB);
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
complex<DP> ln_Fn_F_B_0, ln_Fn_G_0, ln_Fn_G_2;
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
//re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
//im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
ln_Fn_F_B_0 = ln_Fn_F(B, j, alpha, 0);
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F_B_0);
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F_B_0);
|
||||
//re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
//im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
ln_Fn_G_0 = ln_Fn_G(A, B, j, alpha, 0);
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G_0);
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G_0);
|
||||
//re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
//im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
ln_Fn_G_0 = ln_Fn_G(A, B, j, alpha, 2);
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G_2);
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G_2);
|
||||
}
|
||||
}
|
||||
|
||||
DP logsinzeta = log(sin(A.chain.anis));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
|
||||
}
|
||||
|
||||
//ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
|
||||
ln_prod3 -= A.base.Mdown * logsinzeta;
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
//ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
|
||||
ln_prod4 -= B.base.Mdown * logsinzeta;
|
||||
|
||||
// Now proceed to build the Hm2P matrix
|
||||
|
||||
SQMat_CX Hm2P(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> two_over_A_sinhlambda_sq_plus_sinzetaover2sq;
|
||||
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
two_over_A_sinhlambda_sq_plus_sinzetaover2sq = 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
* (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
+ pow(sin(0.5*A.chain.anis), 2.0));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logsinzeta);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logsinzeta);
|
||||
|
||||
Prod_powerN = pow( B.chain.par[k] == 1 ?
|
||||
(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
:
|
||||
(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
, complex<DP> (B.chain.Nsites));
|
||||
|
||||
//cout << "Prod_powerN = " << Prod_powerN << "\t" << abs(Prod_powerN) << endl;
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq
|
||||
* exp(II*im_ln_Fn_F_B_0[k][beta] + logsinzeta);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logsinzeta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logsinzeta);
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinhlambda_sq_plus_sinzetaover2sq);
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> ln_det = lndet_LU_CX_dstry(Hm2P);
|
||||
|
||||
complex<DP> ln_ME = log(0.5 * sqrt(A.chain.Nsites)) + ln_prod1 - ln_prod2 - ln_prod3 + ln_prod4 + 2.0 * ln_det - A.lnnorm - B.lnnorm;
|
||||
|
||||
//cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm
|
||||
//<< "\t" << re_ln_det << "\t" << ln_form_factor_sq << endl;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(ln_ME); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,304 @@
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
/*
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(-II * sin(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.eta * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))));
|
||||
*/
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b))) {
|
||||
|
||||
// arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// absarg = abs(arg);
|
||||
|
||||
prod_temp *= -II * (B.sinlambda[j][alpha] * B.coslambda[k][beta] - B.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(B.coslambda[j][alpha] * B.coslambda[k][beta] + B.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (counter++ > 10) { // we do at most 10 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
// return(ans);
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
/*
|
||||
prod_temp *= -II * sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.eta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
*/
|
||||
|
||||
// arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// absarg = abs(arg);
|
||||
|
||||
prod_temp *= -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
|
||||
if (counter++ > 25) { // we do at most 25 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
}}}
|
||||
|
||||
// return(ans);
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXZ_gpd_Bethe_State& A, int j, int alpha, int a, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
/*
|
||||
return(-1.0/(sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)))));
|
||||
*/
|
||||
|
||||
// int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// int absarg1 = abs(arg1);
|
||||
// int arg2 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b - 1);
|
||||
// int arg2 = arg1 + 2;
|
||||
// int absarg2 = abs(arg2);
|
||||
|
||||
return(1.0/(( -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))) *
|
||||
(-II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))))));
|
||||
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXZ_gpd_Bethe_State& A, int j, int alpha, int a, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
/*
|
||||
complex<DP> ans = -II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))));
|
||||
|
||||
return (ans * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
*/
|
||||
return (-II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Sz_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXZ_gpd_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXZ_gpd_Chains in Sz matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
|
||||
|
||||
if (A.iK == B.iK && (A.label != B.label))
|
||||
return(-300.0); // matrix element identically vanishes
|
||||
|
||||
// Compute the sin and cos of rapidities
|
||||
|
||||
A.Compute_sinlambda();
|
||||
A.Compute_coslambda();
|
||||
B.Compute_sinlambda();
|
||||
B.Compute_coslambda();
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(sin(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(sin(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(sin(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
DP logabssinheta = log(abs(sinh(A.chain.anis)));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);
|
||||
|
||||
ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
ln_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis)));
|
||||
|
||||
// Now proceed to build the Hm2P matrix
|
||||
|
||||
SQMat_CX Hm2P(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> two_over_A_sinlambda_sq_plus_sinhetaover2sq = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
two_over_A_sinlambda_sq_plus_sinhetaover2sq = -2.0/((sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
|
||||
+ 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a))) *
|
||||
(sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
|
||||
+ 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)))
|
||||
+ pow(sinh(0.5*A.chain.anis), 2.0));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
|
||||
|
||||
Prod_powerN = pow((B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1]),
|
||||
complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
|
||||
- two_over_A_sinlambda_sq_plus_sinhetaover2sq * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinheta);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinheta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinheta);
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinlambda_sq_plus_sinhetaover2sq);
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
+ 2.0 * real(lndet_LU_CX_dstry(Hm2P)) - A.lnnorm - B.lnnorm;
|
||||
|
||||
//cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm << "\t"
|
||||
// << lndet_LU_CX(Hm2P) << endl;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,502 @@
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
namespace JSC {
|
||||
inline complex<DP> phi(complex<DP> x){return x;}
|
||||
inline complex<DP> a(complex<DP> x){return 1;}
|
||||
inline complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta){ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
|
||||
inline complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
|
||||
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
|
||||
complex<DP> ln_Szm_p_Smz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
|
||||
{
|
||||
//clock_t start_time_local = clock();
|
||||
//A has to be the ground state!
|
||||
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXX_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Szm_p_Smz matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown + 1) JSCerror("Incompatible Mdown between the two states in SzSm_p_SmSz matrix element!");
|
||||
|
||||
//if (B.type_id > 999999LL) return(complex<DP>(-300.0));
|
||||
|
||||
//add a delta to the origin of the centered strings
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
if(abs(A.lambda[i][alpha])<5.55112e-12)A.lambda[i][alpha]=5.55112e-12;
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
if(abs(B.lambda[i][alpha])<5.55112e-5)B.lambda[i][alpha]=5.55112e-5;
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
complex<DP> i=complex<DP>(0.0,1.0);
|
||||
complex<DP> eta=-i;
|
||||
complex<DP> ln_prod = complex<DP>(0.0,0.0);
|
||||
complex<DP> result;
|
||||
result=log(B.chain.Nsites*1.0/4.0);
|
||||
|
||||
int sizeA=0;
|
||||
int sizeB=0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
sizeA+=A.base.Nrap[i]*A.chain.Str_L[i];
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
sizeB+=B.base.Nrap[i]*B.chain.Str_L[i];
|
||||
|
||||
complex<DP>* mu = new complex<DP>[sizeA];
|
||||
complex<DP>* lam = new complex<DP>[sizeB];
|
||||
int index=0;
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
{
|
||||
// mu[index]=(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
mu[index]=(A.lambda[i][alpha] + 0.5 * -eta * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
index++;
|
||||
}
|
||||
|
||||
index=0;
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
{
|
||||
// lam[index]=(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
lam[index]=(B.lambda[i][alpha] + 0.5 * -eta * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
index++;
|
||||
}
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
// for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
// for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
// ln_prod+=log(abs(phi((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a))+eta*0.5)))
|
||||
|
||||
// for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
// for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
// for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
// ln_prod+=-log(abs(phi(-(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a))+eta*0.5)));
|
||||
|
||||
// for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
// for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
// for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
// for (int j = 0; j < B.chain.Nstrings; ++j)
|
||||
// for (int beta = 0; beta < B.base.Nrap[j]; ++beta)
|
||||
// for (int b = 1; b <= B.chain.Str_L[j]; ++b)
|
||||
// if(i!=j || alpha!=beta ||a!=b)ln_prod3+=-0.5*log(abs(phi((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a))-(B.lambda[j][beta] + 0.5 * II * (B.chain.Str_L[j] + 1.0 - 2.0 * b))-eta)));
|
||||
|
||||
// for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
// for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
// for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
// for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
// for (int beta = 0; beta < A.base.Nrap[j]; ++beta)
|
||||
// for (int b = 1; b <= A.chain.Str_L[j]; ++b)
|
||||
// if(abs((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a))-(A.lambda[j][beta] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * b))-eta)!=0 && (i!=j && alpha!=beta && a!=b))
|
||||
// ln_prod3+=-0.5*log(abs((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a))-(A.lambda[j][beta] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * b))-eta));
|
||||
|
||||
|
||||
|
||||
//mu is the ground state!
|
||||
//A -> mu, B -> lam
|
||||
complex<DP> prod=complex<DP>(1.0,0.0);
|
||||
complex<DP> prod2=complex<DP>(1.0,0.0);
|
||||
complex<DP> prod3=complex<DP>(1.0,0.0);
|
||||
for(int l=0; l<sizeA;l++) prod*=phi(mu[l]+eta*0.5);
|
||||
for(int l=0; l<sizeB;l++) prod/=phi(lam[l]+eta*0.5);
|
||||
|
||||
for(int l=0; l<sizeA;l++)
|
||||
for(int m=0; m<sizeA;m++)
|
||||
if(l!=m)prod2*=1.0/sqrt(abs(phi(mu[m]-mu[l]-eta)));
|
||||
for(int l=0; l<sizeB;l++)
|
||||
for(int m=0; m<sizeB;m++)
|
||||
if(abs(lam[m]-lam[l]-eta)!=0 && l!=m)prod3*=1.0/sqrt(abs(phi(lam[m]-lam[l]-eta)));
|
||||
|
||||
result+=2.0*log(abs(prod))-2.0*log(prod3)+2.0*log(prod2) - A.lnnorm - B.lnnorm;// a factor prod3^2 is inserted in the determinant!
|
||||
// cout<<"prod:"<<prod<<endl;
|
||||
SQMat_CX Hm(0.0, A.base.Mdown);
|
||||
//complex<DP> H[sizeA][sizeA];
|
||||
// cout<<"mu[l]:";
|
||||
// for(int l=0; l<sizeA;l++)
|
||||
// cout<<mu[l]<<", ";
|
||||
// cout<<endl;
|
||||
// cout<<"lam[l]:";
|
||||
// for(int l=0; l<sizeB;l++)
|
||||
// cout<<lam[l]<<", ";
|
||||
// cout<<endl;
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
complex<DP> Prod_powerN;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
complex<DP> prodplus= complex<DP>(1.0,0.0);
|
||||
complex<DP> prodminus= complex<DP>(1.0,0.0);
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
|
||||
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
|
||||
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
|
||||
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] -eta*0.5) /(B.lambda[k][beta] +eta*0.5), complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
|
||||
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
|
||||
if (b > 1) Hm[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)*exp(ln_Fn_G(A,B,k,beta,b-1))*exp(-real(ln_Fn_F(B, k, beta, b - 1)));//.../ prod_l!=k | phi(lam[l]-lam[k]) |
|
||||
else if (b == 1) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
complex<DP> sum1 = complex<DP>(0.0,0.0);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1] //sum term when i=0
|
||||
- ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) //sum term when i=n
|
||||
* exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
|
||||
Hm[index_a][index_b] = eta * exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum1 * exp( - real(ln_Fn_F(B, k, beta, b - 1))); //the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements Hm[a][M]
|
||||
|
||||
//Hm[index_a][B.base.Mdown] = one_over_A_lambda_sq_plus_1over2sq;
|
||||
//Hm[index_a][B.base.Mdown] = eta/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
|
||||
// (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
|
||||
Hm[index_a][B.base.Mdown] = eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
// cout<<"Hm:";
|
||||
// for(int j=0; j<sizeA;j++){
|
||||
// for(int k=0; k<sizeA;k++) cout<<"Hm["<<j<<"]["<<k<<"]:"<<Hm[j][k]<<", ";
|
||||
// cout<<endl;
|
||||
// }
|
||||
|
||||
complex<DP> F= complex<DP>(0.0,0.0);
|
||||
|
||||
complex<DP> detmatrix;
|
||||
detmatrix=exp(lndet_LU_CX_dstry(Hm));
|
||||
//cout<<"exp(lndet_LU_CX(Hm)):"<<abs(detmatrix)<<endl;
|
||||
// cout<<"exp(i*(A.K-B.K))+1.0):"<<exp(i*(A.K-B.K))+1.0<<"det(matrix):"<<detmatrix<<endl;
|
||||
//F=-(exp(-i*(A.K-B.K))+1.0)*detmatrix;
|
||||
|
||||
//mu is the ground state!
|
||||
//A -> mu, B -> lam
|
||||
SQMat_CX G(0.0, A.base.Mdown);
|
||||
SQMat_CX BbDa(0.0, A.base.Mdown);
|
||||
index_a = 0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
complex<DP> Da;
|
||||
complex<DP> Ca;
|
||||
Da=eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
|
||||
Ca=eta*((mu[index_a]-eta*0.5)+(mu[index_a]+eta*0.5))/pow(((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5)),2.0);
|
||||
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
/*if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
complex<DP> Bb;
|
||||
Bb=-(phi(lam[index_b]+eta*0.5)+phi(lam[index_b]-eta*0.5));
|
||||
complex<DP> product=complex<DP>(1.0,0.0);
|
||||
for(int o=0; o<sizeB;o++)product*=phi(lam[o]-lam[index_b]+eta);
|
||||
Bb*=product;
|
||||
|
||||
complex<DP> prodplus= complex<DP>(1.0,0.0);
|
||||
complex<DP> prodminus= complex<DP>(1.0,0.0);
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
|
||||
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
|
||||
//prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta]);// - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
|
||||
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
|
||||
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
|
||||
// prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta]);// - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] - eta*0.5) /(B.lambda[k][beta] + eta*0.5), complex<DP> (B.chain.Nsites));
|
||||
|
||||
G[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
|
||||
BbDa[index_a][index_b]=Bb*Da*exp(- re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
*/{
|
||||
|
||||
if (b > 1){
|
||||
G[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)*exp(ln_Fn_G(A,B,k,beta,b-1))*exp(-real(ln_Fn_F(B, k, beta, b - 1)));//.../ prod_l!=k | phi(lam[l]-lam[k]) |
|
||||
BbDa[index_a][index_b] =0 ;
|
||||
}
|
||||
else if (b == 1) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
complex<DP> sum1 = complex<DP>(0.0,0.0);
|
||||
complex<DP> sum2 = complex<DP>(0.0,0.0);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1]
|
||||
- ln_FunctionF[0] - ln_FunctionF[1]);//sum term when i=0
|
||||
//sum2 doesn't have a i=0 term
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); //sum term when i=n
|
||||
sum2 += exp(ln_FunctionG[B.chain.Str_L[k]]- ln_FunctionF[B.chain.Str_L[k]] )
|
||||
* (phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * B.chain.Str_L[k]))-eta*0.5)
|
||||
+ phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * B.chain.Str_L[k]))+eta*0.5) ); //sum term when i=n
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) {
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
sum2 += exp(ln_FunctionG[jsum]- ln_FunctionF[jsum] )
|
||||
* (phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * jsum))-eta*0.5)
|
||||
+ phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * jsum))+eta*0.5) );
|
||||
}
|
||||
|
||||
G[index_a][index_b] = eta * exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum1 * exp( - real(ln_Fn_F(B, k, beta, b - 1))); //the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
|
||||
BbDa[index_a][index_b] = - Da* exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum2 * exp( - real(ln_Fn_F(B, k, beta, b - 1)));//the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements Hm[a][M]
|
||||
|
||||
|
||||
//Hm[index_a][B.base.Mdown] = eta/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) * (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
|
||||
G[index_a][B.base.Mdown]=Ca;
|
||||
BbDa[index_a][B.base.Mdown]=0;
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
SQMat_CX matrix(0.0, A.base.Mdown);
|
||||
for(int a=0; a<sizeA;a++)
|
||||
for(int b=0; b<sizeA;b++)
|
||||
matrix[a][b]=G[a][b]+BbDa[a][b];
|
||||
|
||||
// cout<<"matrix:";
|
||||
// for(int j=0; j<sizeA;j++){
|
||||
// for(int k=0; k<sizeA;k++) cout<<"matrix["<<j<<"]["<<k<<"]:"<<matrix[j][k]<<", ";
|
||||
// cout<<endl;
|
||||
// }
|
||||
// cout<<"matrixtest:";
|
||||
// for(int j=0; j<sizeA;j++){
|
||||
// for(int k=0; k<sizeA;k++) cout<<"matrixtest["<<j<<"]["<<k<<"]:"<<matrixtest[j][k]<<", ";
|
||||
// cout<<endl;
|
||||
// }
|
||||
|
||||
// cout<<"BbDa[a][b]:";
|
||||
// for(int j=0; j<sizeA;j++){
|
||||
// for(int k=0; k<sizeA;k++) cout<<"BbDa["<<j<<"]["<<k<<"]:"<<BbDa[j][k]<<", ";
|
||||
// cout<<endl;
|
||||
// }
|
||||
// cout<<"Bn[b]*Da[a]:";
|
||||
// for(int j=0; j<sizeA;j++){
|
||||
// for(int k=0; k<sizeA;k++) cout<<"test["<<j<<"]["<<k<<"]:"<<Bn[k]*Da[j]<<", ";
|
||||
// cout<<endl;
|
||||
// }
|
||||
|
||||
// cout<<"prod:"<<prod<<endl;
|
||||
// cout<<"(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G))):"<<(exp(lndet_LU_CX(matrix))-exp(lndet_LU_CX(G)))<<endl;
|
||||
// cout<<"(exp(lndet_LU_CX_dstry(matrix)):"<<(exp(lndet_LU_CX(matrix)))<<endl;
|
||||
|
||||
//cout<<" an(n):"<<an(n)<<" det(matrix):"<<det(matrix)<< " det(Gn):"<<det(Gn)<<" an(n)*(det(matrix)-det(Gn)):"<<an(n)*(det(matrix)-det(Gn))<<endl;
|
||||
complex<DP> sum=prod*(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G)));
|
||||
//sum=conj(prod)*(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G)));
|
||||
|
||||
//cout<<"an(n):"<< an(n)<< "det(matrix):"<<det(matrix)<<" det(Gn):"<<det(Gn)<<endl;
|
||||
|
||||
//sum_nm_test=(0.5*(lam[0]-lam[1])*(eta*eta+4.0*lam[0]*lam[1]))/pow((lam[0]-eta/2.0)*(lam[0]+eta/2.0)*(lam[1]-eta/2.0)*(lam[1]+eta/2.0),2.0)*(0.5*(mu[0]-mu[1])*(eta*eta+4.0*mu[0]*mu[1]))/pow((mu[0]-eta/2.0)*(mu[0]+eta/2.0)*(mu[1]-eta/2.0)*(mu[1]+eta/2.0),2.0);
|
||||
//sum_nm_test=(0.5*(lam[0]-lam[1])*(eta*eta+4.0*lam[0]*lam[1]))*(0.5*(mu[0]-mu[1])*(eta*eta+4.0*mu[0]*mu[1]))/pow((mu[0]-eta/2.0)*(mu[0]+eta/2.0)*(mu[1]-eta/2.0)*(mu[1]+eta/2.0),2.0);
|
||||
//cout<<"F1:"<<F<<endl;
|
||||
// F+=4.0*pow(prod,2)*exp(i*(qlam+qmu))*sum_n;
|
||||
|
||||
// F+=+2.0*exp(i*(A.K-B.K))*sum;
|
||||
|
||||
complex<DP> F2=exp(eta*(B.K-A.K))*(-2.0*sum);
|
||||
complex<DP> F3=(exp(eta*(B.K-A.K)))*(detmatrix);
|
||||
F=detmatrix;
|
||||
// cout<<"F1:"<<F*sqrt(exp(result))<<" F2:"<<F2*sqrt(exp(result))<<" F3:"<<F3*sqrt(exp(result))<<endl;
|
||||
// cout<<"abs(F1)^2:"<<abs(F*F*(exp(result)))<<" abs(F2)^2:"<<abs(F2*F2*(exp(result)))<<" abs(F3)^2:"<<abs(F3*F3*(exp(result)))<<endl;
|
||||
// cout<<"arg(F1):"<<-i*log(F*sqrt(exp(result))/abs(F*sqrt(exp(result))))/M_PI<<" arg(F2):"<<-i*log(F2*sqrt(exp(result))/abs(F2*sqrt(exp(result))))/M_PI<<" arg(F3):"<<-i*log(F3*sqrt(exp(result))/abs(F3*sqrt(exp(result))))/M_PI<<endl;
|
||||
// cout<<"F:"<<(F)<<endl;
|
||||
// cout<<"Smff:"<<exp(result)*4.0*abs(detmatrix*detmatrix)<<endl;
|
||||
F+=exp(i*(A.K-B.K))*(2.0*sum*(-1.0)+detmatrix);
|
||||
|
||||
|
||||
// cout<<"sum:"<<sum<<endl;
|
||||
// cout<<"exp(result):"<<exp(result)<<endl;
|
||||
|
||||
//TEST!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
result+=2.0*log(abs(F));
|
||||
result-=log(A.chain.Nsites-A.base.Mdown*2+2.0);
|
||||
//result*=pow(abs((exp(i*(A.K-B.K))+1.0)*detmatrix),2);//*(exp(i*(A.K-B.K))+1.0)
|
||||
//result*=pow(abs(2.0*exp(i*(A.K-B.K))*sum),2);
|
||||
//result/=(B.chain.Nsites)*1/16.0;
|
||||
//cout<<"TEST::::::::::::::::::::::"<<"A.Check_Admissibility('a'):"<<A.Check_Admissibility('a')<<endl;
|
||||
//cout<<"mu:"<<mu<<" lam:"<<lam<<endl;
|
||||
// cout<<"an(n):"<<an<<endl;
|
||||
// cout<<"prod^2:"<<pow(abs(prod),2)<<endl;
|
||||
// cout<<"prod3:"<<prod3<<endl;
|
||||
// cout<<"prod2:"<<prod2<<endl;
|
||||
|
||||
|
||||
// cout<<"normlam"<<"normmu:"<<(exp(A.lnnorm))<<":"<<(exp(B.lnnorm))<<endl;
|
||||
// cout<<"abs(prod*prod*prod2*sum_n):"<<abs(prod*prod*prod2*sum_n)<<endl;
|
||||
|
||||
|
||||
//cout<<"computation time for Szm:"<<clock()-start_time_local<<endl;
|
||||
complex<DP> ln_ME_sq = result;
|
||||
|
||||
// if (real(ln_ME_sq) > 10.0) ln_ME_sq = complex<DP> (-300.0); // fix for artificial divergences
|
||||
|
||||
delete[] mu;
|
||||
delete[] lam;
|
||||
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,417 @@
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
complex<DP> phi(complex<DP> x){return x;}
|
||||
complex<DP> a(complex<DP> x){return 1;}
|
||||
complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta){ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
|
||||
complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
|
||||
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Szz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B){
|
||||
//clock_t start_time_local = clock();
|
||||
//B has to be the ground state!
|
||||
const DP Zero_Center_Thres=1.0e-5;
|
||||
const DP real_dev=1.0e-14;
|
||||
const DP Diff_ME_Thres=1.e-6;
|
||||
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXX_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Szz matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) JSCerror("Incompatible Mdown between the two states in Szz matrix element!");
|
||||
|
||||
complex<DP> eta=-II;
|
||||
complex<DP> ln_prod = complex<DP>(0.0,0.0);
|
||||
complex<DP> result=-300;
|
||||
complex<DP> prev_result=-300;
|
||||
|
||||
//if(A.String_delta()> HEIS_deltaprec) return(complex<DP>(-300.0)); // DEPRECATED in ++T_9
|
||||
|
||||
if((A.E)==(B.E) && B.chain.Nsites ==B.base.Mdown*2){
|
||||
return(2*log(abs((B.E+(B.chain.Nsites)/4.0)/(3.0*sqrt(B.chain.Nsites)))));
|
||||
}
|
||||
|
||||
XXX_Bethe_State A_origin; A_origin=A;
|
||||
bool zero_string=false;
|
||||
for (int j = 0; j < A_origin.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A_origin.base.Nrap[j]; ++alpha)
|
||||
if(abs(A_origin.lambda[j][alpha])<Zero_Center_Thres) zero_string=true;
|
||||
|
||||
// Some convenient arrays
|
||||
bool real_dev_conv=false;
|
||||
int dev=-1;
|
||||
while(!real_dev_conv){
|
||||
real_dev_conv=true;
|
||||
|
||||
dev++;
|
||||
|
||||
//add a delta to the origin of the centered strings
|
||||
if(zero_string){
|
||||
real_dev_conv=false;
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
if(abs(A_origin.lambda[j][alpha])<Zero_Center_Thres)
|
||||
A.lambda[j][alpha]=real_dev*pow(10.0,dev);
|
||||
}
|
||||
|
||||
|
||||
prev_result=result;
|
||||
|
||||
//add manualy the ground state value
|
||||
|
||||
|
||||
|
||||
|
||||
int sizeA=0;
|
||||
int sizeB=0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
sizeA+=A.base.Nrap[i]*A.chain.Str_L[i];
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
sizeB+=B.base.Nrap[i]*B.chain.Str_L[i];
|
||||
|
||||
complex<DP>* mu = new complex<DP>[sizeA];
|
||||
complex<DP>* lam = new complex<DP>[sizeB];
|
||||
int index=0;
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
{
|
||||
mu[index]=(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
index++;
|
||||
}
|
||||
|
||||
index=0;
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
{
|
||||
lam[index]=(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
index++;
|
||||
}
|
||||
|
||||
Lambda re_ln_Fn_F_A_0(A.chain, A.base);
|
||||
Lambda im_ln_Fn_F_A_0(A.chain, A.base);
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_A_0[j][alpha] = real(ln_Fn_F(A, j, alpha, 0));
|
||||
im_ln_Fn_F_A_0[j][alpha] = imag(ln_Fn_F(A, j, alpha, 0));
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int k = 0; k < A.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < A.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= A.chain.Str_L[k]; ++b) {
|
||||
if (b == 1)ln_prod3 += re_ln_Fn_F_A_0[k][beta];
|
||||
else if (b > 1) ln_prod3 += ln_Fn_F(A, k, beta, b - 1);/*TEST*/
|
||||
}
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
|
||||
complex<DP> prod=complex<DP>(1.0,0.0);
|
||||
for(int l=0; l<sizeA;l++) prod*=phi(mu[l]+eta*0.5);
|
||||
for(int l=0; l<sizeB;l++) prod/=phi(lam[l]+eta*0.5);
|
||||
|
||||
double factor = log((B.chain.Nsites)*1/16.0);
|
||||
factor +=(2.0*log(abs(prod)) - real(ln_prod3) + real(ln_prod4) - A.lnnorm - B.lnnorm);// a factor prod4^-2 is inserted in the determinant!
|
||||
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
complex<DP> Prod_powerN;
|
||||
|
||||
|
||||
SQMat_CX H(0.0, A.base.Mdown);
|
||||
SQMat_CX P(0.0, A.base.Mdown);
|
||||
index_a = 0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
complex<DP> Da;
|
||||
complex<DP> Ca;
|
||||
Da=eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
|
||||
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
complex<DP> Bb=complex<DP>(1.0,0.0);
|
||||
for(int o=0; o<sizeB;o++)Bb*=phi(lam[o]-lam[index_b]+eta);
|
||||
|
||||
complex<DP> prodplus= complex<DP>(1.0,0.0);
|
||||
complex<DP> prodminus= complex<DP>(1.0,0.0);
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);
|
||||
|
||||
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);
|
||||
|
||||
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] - eta*0.5) /(B.lambda[k][beta] + eta*0.5), complex<DP> (B.chain.Nsites));
|
||||
|
||||
H[index_a][index_b] = eta*(prodplus-prodminus*Prod_powerN);
|
||||
P[index_a][index_b] = Bb*Da*exp(- re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
|
||||
if (b > 1){
|
||||
H[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)*exp(ln_Fn_G(A,B,k,beta,b-1))*exp(-real(ln_Fn_F(B, k, beta, b - 1)));//.../ prod_l!=k | phi(lam[l]-lam[k]) |
|
||||
P[index_a][index_b] =0 ;
|
||||
}
|
||||
else if (b == 1) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
complex<DP> sum1 = complex<DP>(0.0,0.0);
|
||||
complex<DP> sum2 = complex<DP>(0.0,0.0);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1]
|
||||
- ln_FunctionF[0] - ln_FunctionF[1]);//sum term when i=0
|
||||
//sum2 doesn't have a i=0 term
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); //sum term when i=n
|
||||
sum2 += exp(ln_FunctionG[B.chain.Str_L[k]]- ln_FunctionF[B.chain.Str_L[k]] ); //sum term when i=n
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) {
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
sum2 += exp(ln_FunctionG[jsum]- ln_FunctionF[jsum] );
|
||||
}
|
||||
|
||||
H[index_a][index_b] = eta * exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum1 * exp( - real(ln_Fn_F(B, k, beta, b - 1))); //the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
|
||||
P[index_a][index_b] = - Da* exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum2 * exp( - real(ln_Fn_F(B, k, beta, b - 1)));//the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> F= complex<DP>(0.0,0.0);
|
||||
|
||||
|
||||
SQMat_CX matrix(0.0, A.base.Mdown);
|
||||
for(int j=0; j<sizeA;j++)
|
||||
for(int k=0; k<sizeA;k++){
|
||||
matrix[j][k]=(H[j][k]-2.0*P[j][k]);
|
||||
}
|
||||
complex<DP> detmatrix;
|
||||
detmatrix=exp(lndet_LU_CX_dstry(matrix)+0.5*factor);
|
||||
|
||||
SQMat_CX Gn(0.0, A.base.Mdown);
|
||||
|
||||
complex<DP> sum_n=complex<DP>(0.0,0.0);
|
||||
for(int n=0; n<sizeA;n++){
|
||||
complex<DP> An;
|
||||
An=-phi(lam[n]-eta*0.5);
|
||||
for(int m=0; m<sizeA;m++)
|
||||
An*=phi(lam[m]-lam[n]+eta);
|
||||
|
||||
SQMat_CX Gn(0.0, A.base.Mdown);
|
||||
SQMat_CX BnbDa(0.0, A.base.Mdown);
|
||||
index_a = 0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
complex<DP> Da;
|
||||
complex<DP> Ca;
|
||||
Da=eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
|
||||
Ca=(eta)*((mu[index_a]-eta*0.5)+(mu[index_a]+eta*0.5))/pow(((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5)),2.0);
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if(index_b==n){
|
||||
Gn[index_a][index_b] = Ca*exp(-real(ln_Fn_F(B, k, beta, b - 1)));
|
||||
BnbDa[index_a][index_b] = 0;
|
||||
} // else (index_b!=n)
|
||||
else if (B.chain.Str_L[k] == 1) {
|
||||
complex<DP> Bnb;
|
||||
Bnb=-phi(lam[index_b]+eta*0.5)/phi(lam[n]-lam[index_b]-eta);
|
||||
complex<DP> product=complex<DP>(1.0,0.0);
|
||||
for(int o=0; o<sizeB;o++)product*=phi(lam[o]-lam[index_b]+eta);
|
||||
Bnb*=product;
|
||||
|
||||
complex<DP> prodplus= complex<DP>(1.0,0.0);
|
||||
complex<DP> prodminus= complex<DP>(1.0,0.0);
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
|
||||
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
|
||||
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
|
||||
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] - eta*0.5) /(B.lambda[k][beta] + eta*0.5), complex<DP> (B.chain.Nsites));
|
||||
|
||||
Gn[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
|
||||
BnbDa[index_a][index_b]=Bnb*Da*exp(- re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else{
|
||||
JSCerror("The Szz matrix element computation is not able to handle string states in the B.state (second argument). This is in development...");
|
||||
|
||||
} // else
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
SQMat_CX matrix(0.0, A.base.Mdown);
|
||||
for(int a=0; a<sizeA;a++)
|
||||
for(int b=0; b<sizeA;b++)
|
||||
matrix[a][b]=Gn[a][b]+BnbDa[a][b];
|
||||
sum_n+=(exp(lndet_LU_CX_dstry(matrix)+0.5*factor+log(An))-exp(lndet_LU_CX_dstry(Gn)+0.5*factor+log(An)));
|
||||
}// sum over n
|
||||
sum_n*=prod;
|
||||
|
||||
F=(exp(II*(A.K-B.K))+1.0)*detmatrix;
|
||||
F+=-4.0*exp(II*(A.K-B.K))*sum_n;
|
||||
|
||||
result=2*log(abs(F));
|
||||
|
||||
if (!(real_dev_conv) && abs(exp(result)-exp(prev_result))<abs( Diff_ME_Thres*exp(result))){
|
||||
real_dev_conv=true;
|
||||
}
|
||||
|
||||
if (!(real_dev_conv) && dev >20){
|
||||
result=-300;
|
||||
real_dev_conv=true;
|
||||
}
|
||||
|
||||
delete[] mu;
|
||||
delete[] lam;
|
||||
|
||||
}
|
||||
|
||||
//return(result);
|
||||
return(0.5 * result); // Return ME, not MEsq
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,25 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Infprec.cc
|
||||
|
||||
Purpose: Definitions for infinite precision arithmetic classes.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
//***************************************************************************************************
|
||||
|
||||
|
||||
|
||||
} // namespace JSC
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,152 @@
|
||||
/****************************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c) 2006.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
Integration_par.cc
|
||||
|
||||
Defines all functions to perform integration of functions, parallel (MPI).
|
||||
|
||||
LAST MODIFIED: 30/10/06
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
void Improve_estimate_par (MPI_Comm comm, Integral_data& integdat, DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, int max_nr_pts)
|
||||
{
|
||||
// This function is only ever called by process rank 0.
|
||||
|
||||
// We generate a max of 3* n_vals points
|
||||
data_pt* new_data = new data_pt[3* integdat.integ_res.n_vals];
|
||||
DP* new_abs_d2f_dx = new DP[integdat.integ_res.n_vals];
|
||||
|
||||
// Check points in batches of 3; if needed, improve
|
||||
int threei = 0;
|
||||
int index_new = 0;
|
||||
int i, j;
|
||||
|
||||
integdat.integ_res.abs_prec = 0.0;
|
||||
integdat.integ_res.integ_est = 0.0;
|
||||
|
||||
DP new_max_abs_d2f_dx = 0.0;
|
||||
|
||||
for (i = 0; i < integdat.integ_res.n_vals/3; ++i) {
|
||||
|
||||
threei = 3 * i;
|
||||
|
||||
if (integdat.abs_d2f_dx[i] <= 0.1 * integdat.max_abs_d2f_dx || index_new + integdat.integ_res.n_vals - threei > max_nr_pts) {
|
||||
|
||||
// simply transfer the data points into new_data
|
||||
new_abs_d2f_dx[index_new/3] = integdat.abs_d2f_dx[i];
|
||||
new_max_abs_d2f_dx = JSC::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3]);
|
||||
for (j = 0; j < 3; ++j) {
|
||||
new_data[index_new].x = integdat.data[threei + j].x;
|
||||
new_data[index_new].f = integdat.data[threei + j].f;
|
||||
new_data[index_new].dx = integdat.data[threei + j].dx;
|
||||
integdat.integ_res.integ_est += new_data[index_new].dx * new_data[index_new].f;
|
||||
index_new++;
|
||||
}
|
||||
integdat.integ_res.abs_prec += abs_d2f_dx[i];
|
||||
|
||||
}
|
||||
|
||||
else { // create six new entries and transfer the three existing ones
|
||||
|
||||
new_data[index_new].dx = integdat.data[threei].dx/3.0;
|
||||
for (j = 1; j < 9; ++j) new_data[index_new + j].dx = new_data[index_new].dx;
|
||||
|
||||
new_data[index_new].x = integdat.data[threei].x - new_data[index_new].dx;
|
||||
new_data[index_new + 1].x = integdat.data[threei].x;
|
||||
new_data[index_new + 2].x = integdat.data[threei].x + new_data[index_new].dx;
|
||||
|
||||
new_data[index_new + 3].x = integdat.data[threei + 1].x - new_data[index_new].dx;
|
||||
new_data[index_new + 4].x = integdat.data[threei + 1].x;
|
||||
new_data[index_new + 5].x = integdat.data[threei + 1].x + new_data[index_new].dx;
|
||||
|
||||
new_data[index_new + 6].x = integdat.data[threei + 2].x - new_data[index_new].dx;
|
||||
new_data[index_new + 7].x = integdat.data[threei + 2].x;
|
||||
new_data[index_new + 8].x = integdat.data[threei + 2].x + new_data[index_new].dx;
|
||||
|
||||
args[arg_to_integ] = new_data[index_new].x;
|
||||
new_data[index_new].f = function(args, Itable);
|
||||
new_data[index_new + 1].f = integdat.data[threei].f;
|
||||
args[arg_to_integ] = new_data[index_new + 2].x;
|
||||
new_data[index_new + 2].f = function(args, Itable);
|
||||
|
||||
args[arg_to_integ] = new_data[index_new + 3].x;
|
||||
new_data[index_new + 3].f = function(args, Itable);
|
||||
new_data[index_new + 4].f = integdat.data[threei + 1].f;
|
||||
args[arg_to_integ] = new_data[index_new + 5].x;
|
||||
new_data[index_new + 5].f = function(args, Itable);
|
||||
|
||||
args[arg_to_integ] = new_data[index_new + 6].x;
|
||||
new_data[index_new + 6].f = function(args, Itable);
|
||||
new_data[index_new + 7].f = integdat.data[threei + 2].f;
|
||||
args[arg_to_integ] = new_data[index_new + 8].x;
|
||||
new_data[index_new + 8].f = function(args, Itable);
|
||||
|
||||
new_abs_d2f_dx[index_new/3] = fabs(new_data[index_new].dx * (new_data[index_new].f - 2.0 * new_data[index_new + 1].f + new_data[index_new + 2].f));
|
||||
new_abs_d2f_dx[index_new/3 + 1] = fabs(new_data[index_new].dx * (new_data[index_new + 3].f - 2.0 * new_data[index_new + 4].f + new_data[index_new + 5].f));
|
||||
new_abs_d2f_dx[index_new/3 + 2] = fabs(new_data[index_new].dx * (new_data[index_new + 6].f - 2.0 * new_data[index_new + 7].f + new_data[index_new + 8].f));
|
||||
|
||||
new_max_abs_d2f_dx = JSC::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3]);
|
||||
new_max_abs_d2f_dx = JSC::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3 + 1]);
|
||||
new_max_abs_d2f_dx = JSC::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3 + 2]);
|
||||
|
||||
integdat.integ_res.integ_est += new_data[index_new].dx * (new_data[index_new].f + new_data[index_new + 1].f + new_data[index_new + 2].f
|
||||
+ new_data[index_new + 3].f + new_data[index_new + 4].f + new_data[index_new + 5].f
|
||||
+ new_data[index_new + 6].f + new_data[index_new + 7].f + new_data[index_new + 8].f);
|
||||
|
||||
integdat.integ_res.abs_prec += new_abs_d2f_dx[index_new/3] + new_abs_d2f_dx[index_new/3 + 1] + new_abs_d2f_dx[index_new/3 + 2];
|
||||
|
||||
index_new += 9;
|
||||
|
||||
} // else
|
||||
|
||||
} // for (i < nvals/3)
|
||||
|
||||
integdat.integ_res.rel_prec = integdat.integ_res.abs_prec/integdat.integ_res.integ_est;
|
||||
|
||||
integdat.integ_res.n_vals = index_new;
|
||||
|
||||
delete[] integdat.data;
|
||||
integdat.data = new_data;
|
||||
|
||||
integdat.max_abs_d2f_dx = new_max_abs_d2f_dx;
|
||||
|
||||
delete[] integdat.abs_d2f_dx;
|
||||
integdat.abs_d2f_dx = new_abs_d2f_dx;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Integral_result Integrate_optimal_par_using_table (MPI_Comm comm, DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ,
|
||||
I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile)
|
||||
{
|
||||
if (xmax < xmin) JSCerror("Use xmax > xmin in Integrate.");
|
||||
|
||||
Integral_data integ_dat (function, args, arg_to_integ, Itable, xmin, xmax);
|
||||
|
||||
while ((integ_dat.integ_res.rel_prec > req_rel_prec || integ_dat.integ_res.abs_prec > req_abs_prec) && integ_dat.integ_res.n_vals < max_nr_pts) {
|
||||
|
||||
Improve_estimate_par (comm, integ_dat, function, args, arg_to_integ, Itable, max_nr_pts);
|
||||
|
||||
integ_dat.Save (outfile);
|
||||
|
||||
}
|
||||
|
||||
return(integ_dat.integ_res);
|
||||
}
|
||||
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,809 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Bethe_State.cc
|
||||
|
||||
Purpose: Definitions for LiebLin_Bethe_State class.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
//***************************************************************************************************
|
||||
|
||||
// Function definitions: class LiebLin_Bethe_State
|
||||
|
||||
LiebLin_Bethe_State::LiebLin_Bethe_State ()
|
||||
: c_int (0.0), L(0.0), cxL(0.0), N(0),
|
||||
//OriginStateIxe(Vect<int>(0,1)),
|
||||
Ix2_available(Vect<int>(0, 1)), index_first_hole_to_right (Vect<int>(0,1)), displacement (Vect<int>(0,1)),
|
||||
Ix2(Vect<int>(0, 1)), lambdaoc(Vect<DP>(0.0, 1)), //BE(Vect<DP>(0.0, 1)),
|
||||
S(Vect<DP>(0.0, 1)), dSdlambdaoc(Vect<DP>(0.0, 1)),
|
||||
diffsq(0.0), prec(ITER_REQ_PREC_LIEBLIN), conv(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0)
|
||||
{
|
||||
stringstream Nout; Nout << N; label = Nout.str() + LABELSEP + JSCcoding[0] + LABELSEP;//"_0_";
|
||||
}
|
||||
|
||||
LiebLin_Bethe_State::LiebLin_Bethe_State (DP c_int_ref, DP L_ref, int N_ref)
|
||||
: c_int(c_int_ref), L(L_ref), cxL(c_int_ref * L_ref), N(N_ref),
|
||||
//OriginStateIx2(Vect<int>(0,N),
|
||||
Ix2_available(Vect<int>(0, 2)), index_first_hole_to_right (Vect<int>(0,N)), displacement (Vect<int>(0,N)),
|
||||
Ix2(Vect<int>(0, N)), lambdaoc(Vect<DP>(0.0, N)), //BE(Vect<DP>(0.0, N)),
|
||||
S(Vect<DP>(0.0, N)), dSdlambdaoc(Vect<DP>(0.0, N)),
|
||||
diffsq(0.0), prec(JSC::max(1.0, 1.0/(c_int * c_int)) * ITER_REQ_PREC_LIEBLIN), conv(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0)
|
||||
{
|
||||
if (c_int < 0.0) JSCerror("You must use a positive interaction parameter !");
|
||||
if (N < 0) JSCerror("Particle number must be strictly positive.");
|
||||
|
||||
stringstream Nout; Nout << N; label = Nout.str() + LABELSEP + JSCcoding[0] + LABELSEP;//+ "_0_";
|
||||
|
||||
// Set quantum numbers to ground-state configuration:
|
||||
for (int i = 0; i < N; ++i) Ix2[i] = -(N-1) + 2*i;
|
||||
|
||||
Vect<int> OriginIx2 = Ix2;
|
||||
|
||||
(*this).Set_Label_from_Ix2 (OriginIx2);
|
||||
//(*this).Set_Label_Internals_from_Ix2 (OriginIx2);
|
||||
}
|
||||
|
||||
|
||||
LiebLin_Bethe_State& LiebLin_Bethe_State::operator= (const LiebLin_Bethe_State& RefState)
|
||||
{
|
||||
if (this != &RefState) {
|
||||
c_int = RefState.c_int;
|
||||
L = RefState.L;
|
||||
cxL = RefState.cxL;
|
||||
N = RefState.N;
|
||||
label = RefState.label;
|
||||
Ix2_available = RefState.Ix2_available;
|
||||
index_first_hole_to_right = RefState.index_first_hole_to_right;
|
||||
displacement = RefState.displacement;
|
||||
Ix2 = RefState.Ix2;
|
||||
lambdaoc = RefState.lambdaoc;
|
||||
//BE = RefState.BE;
|
||||
S = RefState.S;
|
||||
dSdlambdaoc = RefState.dSdlambdaoc;
|
||||
diffsq = RefState.diffsq;
|
||||
prec = RefState.prec;
|
||||
conv = RefState.conv;
|
||||
iter_Newton = RefState.iter_Newton;
|
||||
E = RefState.E;
|
||||
iK = RefState.iK;
|
||||
K = RefState.K;
|
||||
lnnorm = RefState.lnnorm;
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Set_to_Label (string label_ref, const Vect<int>& OriginStateIx2)
|
||||
{
|
||||
State_Label_Data labeldata = Read_State_Label (label_ref, OriginStateIx2);
|
||||
|
||||
if (N != labeldata.M[0]) {
|
||||
cout << label_ref << endl;
|
||||
cout << labeldata.M << endl;
|
||||
JSCerror("Trying to set an incorrect label on LiebLin_Bethe_State: N != M[0].");
|
||||
}
|
||||
if (N != OriginStateIx2.size()) {
|
||||
cout << label_ref << endl;
|
||||
cout << labeldata.M << endl;
|
||||
JSCerror("Trying to set an incorrect label on LiebLin_Bethe_State: N != OriginStateIx2.size().");
|
||||
}
|
||||
|
||||
label = label_ref;
|
||||
|
||||
Vect<int> OriginStateIx2ordered = OriginStateIx2;
|
||||
OriginStateIx2ordered.QuickSort();
|
||||
|
||||
// Set all Ix2 to OriginState's Ix2:
|
||||
for (int i = 0; i < N; ++i) Ix2[i] = OriginStateIx2ordered[i];
|
||||
|
||||
// Now set the excitations:
|
||||
for (int iexc = 0; iexc < labeldata.nexc[0]; ++iexc)
|
||||
for (int i = 0; i < N; ++i) if (Ix2[i] == labeldata.Ix2old[0][iexc]) Ix2[i] = labeldata.Ix2exc[0][iexc];
|
||||
|
||||
// Now reorder the Ix2 to follow convention:
|
||||
Ix2.QuickSort();
|
||||
|
||||
//cout << "Setting label:" << label_ref << endl << "Ix2old = " << labeldata.Ix2old[0] << endl << "Ix2exc = " << labeldata.Ix2exc[0] << endl;
|
||||
//cout << "on " << OriginStateIx2ordered << endl << "giving " << Ix2 << endl;
|
||||
|
||||
(*this).Set_Label_from_Ix2 (OriginStateIx2ordered);
|
||||
//(*this).Set_Label_Internals_from_Ix2 (OriginStateIx2ordered);
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Set_to_Label (string label_ref)
|
||||
{
|
||||
// This function assumes that OriginState is the ground state.
|
||||
|
||||
Vect<int> OriginStateIx2(N);
|
||||
for (int i = 0; i < N; ++i) OriginStateIx2[i] = -N + 1 + 2*i;
|
||||
|
||||
(*this).Set_to_Label(label_ref, OriginStateIx2);
|
||||
}
|
||||
|
||||
|
||||
void LiebLin_Bethe_State::Set_Label_from_Ix2 (const Vect<int>& OriginStateIx2)
|
||||
{
|
||||
// This function does not assume any ordering of the Ix2.
|
||||
|
||||
if (N != OriginStateIx2.size()) JSCerror("N != OriginStateIx2.size() in Set_Label_from_Ix2.");
|
||||
|
||||
//cout << "Setting label on Ix2 " << endl << Ix2 << endl;
|
||||
|
||||
// Set the state label:
|
||||
Vect<int> type_ref(0,1);
|
||||
Vect<int> M_ref(N, 1);
|
||||
Vect<int> nexc_ref(0, 1);
|
||||
// Count nr of particle-holes:
|
||||
for (int i = 0; i < N; ++i) if (!OriginStateIx2.includes(Ix2[i])) nexc_ref[0] += 1;
|
||||
Vect<Vect<int> > Ix2old_ref(1);
|
||||
Vect<Vect<int> > Ix2exc_ref(1);
|
||||
Ix2old_ref[0] = Vect<int>(JSC::max(nexc_ref[0],1));
|
||||
Ix2exc_ref[0] = Vect<int>(JSC::max(nexc_ref[0],1));
|
||||
int nexccheck = 0;
|
||||
for (int i = 0; i < N; ++i) if (!OriginStateIx2.includes(Ix2[i])) Ix2exc_ref[0][nexccheck++] = Ix2[i];
|
||||
if (nexccheck != nexc_ref[0]) JSCerror("Counting excitations wrong (1) in LiebLin_Bethe_State::Set_Label_from_Ix2");
|
||||
nexccheck = 0;
|
||||
for (int i = 0; i < N; ++i) if (!Ix2.includes (OriginStateIx2[i])) Ix2old_ref[0][nexccheck++] = OriginStateIx2[i];
|
||||
if (nexccheck != nexc_ref[0]) {
|
||||
cout << "nexc_ref[0] = " << nexc_ref[0] << "\tnexccheck = " << nexccheck << endl;
|
||||
cout << OriginStateIx2 << endl;
|
||||
cout << Ix2 << endl;
|
||||
cout << nexc_ref[0] << endl;
|
||||
cout << Ix2old_ref[0] << endl;
|
||||
cout << Ix2exc_ref[0] << endl;
|
||||
JSCerror("Counting excitations wrong (2) in LiebLin_Bethe_State::Set_Label_from_Ix2");
|
||||
}
|
||||
// Now order the Ix2old_ref and Ix2exc_ref:
|
||||
Ix2old_ref[0].QuickSort();
|
||||
Ix2exc_ref[0].QuickSort();
|
||||
|
||||
State_Label_Data labeldata(type_ref, M_ref, nexc_ref, Ix2old_ref, Ix2exc_ref);
|
||||
|
||||
label = Return_State_Label (labeldata, OriginStateIx2);
|
||||
}
|
||||
|
||||
/*
|
||||
void LiebLin_Bethe_State::Set_Label_from_Ix2 (const Vect<int>& OriginStateIx2)
|
||||
{
|
||||
// This function was deprecated since it assumed that the Ix2 of the state were
|
||||
// in a particular order mirroring the indices of OriginStateIx2.
|
||||
|
||||
if (N != OriginStateIx2.size()) JSCerror("N != OriginStateIx2.size() in Set_Label_from_Ix2.");
|
||||
|
||||
Vect<int> OriginStateIx2ordered = OriginStateIx2;
|
||||
OriginStateIx2ordered.QuickSort();
|
||||
|
||||
// Set the state label:
|
||||
Vect<int> type_ref(0,1);
|
||||
Vect<int> M_ref(N, 1);
|
||||
Vect<int> nexc_ref(0, 1);
|
||||
// Count nr of particle-holes:
|
||||
for (int i = 0; i < N; ++i) if (Ix2[i] != OriginStateIx2ordered[i]) nexc_ref[0] += 1;
|
||||
Vect<Vect<int> > Ix2old_ref(1);
|
||||
Vect<Vect<int> > Ix2exc_ref(1);
|
||||
Ix2old_ref[0] = Vect<int>(JSC::max(nexc_ref[0],1));
|
||||
Ix2exc_ref[0] = Vect<int>(JSC::max(nexc_ref[0],1));
|
||||
int nexccheck = 0;
|
||||
for (int i = 0; i < N; ++i)
|
||||
if (Ix2[i] != OriginStateIx2ordered[i]) {
|
||||
Ix2old_ref[0][nexccheck] = OriginStateIx2ordered[i];
|
||||
Ix2exc_ref[0][nexccheck++] = Ix2[i];
|
||||
}
|
||||
|
||||
State_Label_Data labeldata(type_ref, M_ref, nexc_ref, Ix2old_ref, Ix2exc_ref);
|
||||
|
||||
label = Return_State_Label (labeldata);
|
||||
}
|
||||
*/
|
||||
|
||||
void LiebLin_Bethe_State::Set_Label_Internals_from_Ix2 (const Vect<int>& OriginStateIx2)
|
||||
{
|
||||
//JSCerror("LiebLin_Bethe_State::Set_Label_Internals_from_Ix2 deprecated 20110604");
|
||||
|
||||
if (N != OriginStateIx2.size()) JSCerror("N != OriginStateIx2.size() in Set_Label_Internals_from_Ix2.");
|
||||
|
||||
Vect<int> OriginStateIx2ordered = OriginStateIx2;
|
||||
OriginStateIx2ordered.QuickSort();
|
||||
|
||||
// Set the state label:
|
||||
Vect<int> type_ref(0,1);
|
||||
Vect<int> M_ref(N, 1);
|
||||
Vect<int> nexc_ref(0, 1);
|
||||
// Count nr of particle-holes:
|
||||
for (int i = 0; i < N; ++i) if (!OriginStateIx2.includes(Ix2[i])) nexc_ref[0] += 1;
|
||||
Vect<Vect<int> > Ix2old_ref(1);
|
||||
Vect<Vect<int> > Ix2exc_ref(1);
|
||||
Ix2old_ref[0] = Vect<int>(JSC::max(nexc_ref[0],1));
|
||||
Ix2exc_ref[0] = Vect<int>(JSC::max(nexc_ref[0],1));
|
||||
int nexccheck = 0;
|
||||
for (int i = 0; i < N; ++i)
|
||||
if (Ix2[i] != OriginStateIx2ordered[i]) {
|
||||
Ix2old_ref[0][nexccheck] = OriginStateIx2ordered[i];
|
||||
Ix2exc_ref[0][nexccheck++] = Ix2[i];
|
||||
}
|
||||
|
||||
State_Label_Data labeldata(type_ref, M_ref, nexc_ref, Ix2old_ref, Ix2exc_ref);
|
||||
|
||||
label = Return_State_Label (labeldata, OriginStateIx2);
|
||||
|
||||
// Construct the Ix2_available vector: we give one more quantum number on left and right:
|
||||
int navailable = 2 + (JSC::max(Ix2.max(), OriginStateIx2.max()) - JSC::min(Ix2.min(), OriginStateIx2.min()))/2 - N + 1;
|
||||
Ix2_available = Vect<int>(navailable);
|
||||
index_first_hole_to_right = Vect<int>(N);
|
||||
|
||||
// First set Ix2_available to all holes from left
|
||||
for (int i = 0; i < Ix2_available.size(); ++i) Ix2_available[i] = JSC::min(Ix2.min(), OriginStateIx2.min()) - 2 + 2*i;
|
||||
|
||||
// Now shift according to Ix2 of OriginState:
|
||||
for (int j = 0; j < N; ++j) {
|
||||
int i = 0;
|
||||
while (Ix2_available[i] < OriginStateIx2ordered[j]) i++;
|
||||
// We now have Ix2_available[i] == OriginStateIx2[j]. Shift all Ix2_available to the right of this by 2;
|
||||
for (int i1 = i; i1 < navailable; ++i1) Ix2_available[i1] += 2;
|
||||
index_first_hole_to_right[j] = i;
|
||||
}
|
||||
// Ix2_available and index_first_hole_to_right are now fully defined.
|
||||
|
||||
// Now set displacement vector:
|
||||
displacement = Vect<int>(0, N);
|
||||
// Set displacement vector from the Ix2:
|
||||
for (int j = 0; j < N; ++j) {
|
||||
if (Ix2[j] < OriginStateIx2ordered[j]) {
|
||||
// Ix2[j] must be equal to some OriginState_Ix2_available[i] for i < OriginState_index_first_hole_to_right[j]
|
||||
//cout << "Going down\t" << Ix2[j] << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << endl;
|
||||
while (Ix2[j] != Ix2_available[index_first_hole_to_right[j] + displacement[j] ]) {
|
||||
//cout << j << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << "\t" << Ix2_available[index_first_hole_to_right[j] + displacement[j] ] << endl;
|
||||
if (index_first_hole_to_right[j] + displacement[j] == 0) {
|
||||
cout << label << endl << j << endl << OriginStateIx2 << endl << Ix2 << endl << Ix2_available << endl << index_first_hole_to_right << endl << displacement << endl;
|
||||
JSCerror("Going down too far in Set_Label_Internals...");
|
||||
}
|
||||
displacement[j]--;
|
||||
}
|
||||
}
|
||||
if (Ix2[j] > OriginStateIx2ordered[j]) {
|
||||
// Ix2[j] must be equal to some Ix2_available[i] for i >= index_first_hole_to_right[j]
|
||||
//cout << "Going up\t" << Ix2[j] << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << endl;
|
||||
displacement[j] = 1; // start with this value to prevent segfault
|
||||
while (Ix2[j] != Ix2_available[index_first_hole_to_right[j] - 1 + displacement[j] ]) {
|
||||
//cout << j << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << "\t" << Ix2_available[index_first_hole_to_right[j] + displacement[j] ] << endl;
|
||||
if (index_first_hole_to_right[j] + displacement[j] == Ix2_available.size() - 1) {
|
||||
cout << label << endl << j << endl << OriginStateIx2 << endl << Ix2 << endl << Ix2_available << endl << index_first_hole_to_right << endl << displacement << endl;
|
||||
JSCerror("Going up too far in Set_Label_Internals...");
|
||||
}
|
||||
displacement[j]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//cout << "label " << label << endl;
|
||||
//cout << "Ix2: " << Ix2 << endl << "Ix2_available: " << Ix2_available << endl << "index...: " << index_first_hole_to_right << endl << "displacement: " << displacement << endl;
|
||||
//char a; cin >> a;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool LiebLin_Bethe_State::Check_Admissibility (char whichDSF)
|
||||
{
|
||||
//if (Ix2.min() < -13 || Ix2.max() > 13) return(false); // For testing with restricted Hilbert space
|
||||
return(true);
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Find_Rapidities (bool reset_rapidities)
|
||||
{
|
||||
// This function finds the rapidities of the eigenstate
|
||||
|
||||
lnnorm = -100.0; // sentinel value, recalculated if Newton method used in the last step of iteration.
|
||||
|
||||
diffsq = 1.0;
|
||||
|
||||
if (reset_rapidities) (*this).Set_Free_lambdaocs();
|
||||
/*
|
||||
// Start with normal iterations:
|
||||
//for (int niternormal = 0; niternormal < 10; ++niternormal) {
|
||||
for (int niternormal = 0; niternormal < N; ++niternormal) {
|
||||
//(*this).Iterate_BAE(0.99);
|
||||
(*this).Iterate_BAE(0.9);
|
||||
cout << "Normal: " << niternormal << "\t" << diffsq << endl;
|
||||
cout << (*this).lambdaoc << endl;
|
||||
if (diffsq < sqrt(prec)) break;
|
||||
}
|
||||
*/
|
||||
iter_Newton = 0;
|
||||
|
||||
DP damping = 1.0;
|
||||
DP diffsq_prev = 1.0e+6;
|
||||
//while (diffsq > prec && !is_nan(diffsq) && iter_Newton < 40) {
|
||||
while (diffsq > prec && !is_nan(diffsq) && iter_Newton < 100) {
|
||||
//while (diffsq > prec && !is_nan(diffsq) && iter_Newton < 400) {
|
||||
(*this).Iterate_BAE_Newton(damping);
|
||||
//(*this).Iterate_BAE_S(damping); // Not as fast as Newton for N up to ~ 256
|
||||
//if (diffsq > diffsq_prev) damping /= 2.0;
|
||||
if (diffsq > diffsq_prev && damping > 0.5) damping /= 2.0;
|
||||
else if (diffsq < diffsq_prev) damping = 1.0;
|
||||
diffsq_prev = diffsq;
|
||||
//cout << iter_Newton << "\t" << diffsq << "\t" << damping << endl;
|
||||
//cout << (*this).lambdaoc << endl;
|
||||
}
|
||||
|
||||
conv = ((diffsq < prec) && (*this).Check_Rapidities()) ? 1 : 0;
|
||||
|
||||
if (!conv) {
|
||||
cout << "Alert! State " << label << " did not converge... diffsq " << diffsq << "\titer_Newton " << iter_Newton << (*this) << endl;
|
||||
//char a; cin >> a;
|
||||
}
|
||||
|
||||
//cout << (*this) << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool LiebLin_Bethe_State::Check_Rapidities()
|
||||
{
|
||||
bool nonan = true;
|
||||
|
||||
for (int j = 0; j < N; ++j) nonan *= !is_nan(lambdaoc[j]);
|
||||
|
||||
return nonan;
|
||||
}
|
||||
|
||||
DP LiebLin_Bethe_State::String_delta()
|
||||
{
|
||||
return(0.0); // no strings (thus no deviations) in replusive LiebLin
|
||||
}
|
||||
|
||||
bool LiebLin_Bethe_State::Check_Symmetry ()
|
||||
{
|
||||
// Checks whether the I's are symmetrically distributed.
|
||||
|
||||
bool symmetric_state = true;
|
||||
|
||||
Vect<int> Ix2check = Ix2;
|
||||
Ix2check.QuickSort();
|
||||
|
||||
for (int alpha = 0; alpha <= N/2; ++alpha)
|
||||
symmetric_state = symmetric_state && (Ix2check[alpha] == -Ix2check[N - 1 - alpha]);
|
||||
|
||||
return(symmetric_state);
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Compute_lnnorm ()
|
||||
{
|
||||
if (lnnorm == -100.0) { // else Gaudin part already calculated by Newton method
|
||||
|
||||
SQMat_DP Gaudin_Red(N);
|
||||
|
||||
(*this).Build_Reduced_Gaudin_Matrix(Gaudin_Red);
|
||||
|
||||
lnnorm = real(lndet_LU_dstry(Gaudin_Red));
|
||||
|
||||
// Add the pieces outside of Gaudin determinant
|
||||
|
||||
for (int j = 0; j < N - 1; ++j) for (int k = j+1; k < N; ++k) lnnorm += log(1.0 + 1.0/pow(lambdaoc[j] - lambdaoc[k], 2.0));
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Compute_All (bool reset_rapidities) // solves BAE, computes E, K and lnnorm
|
||||
{
|
||||
(*this).Find_Rapidities (reset_rapidities);
|
||||
if (conv == 1) {
|
||||
(*this).Compute_Energy ();
|
||||
(*this).Compute_Momentum ();
|
||||
(*this).Compute_lnnorm ();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Set_Free_lambdaocs()
|
||||
{
|
||||
if (cxL >= 1.0)
|
||||
for (int a = 0; a < N; ++a) lambdaoc[a] = PI * Ix2[a]/cxL;
|
||||
|
||||
// For small values of c, use better approximation using approximate zeroes of Hermite polynomials: see Gaudin eqn 4.71.
|
||||
if (cxL < 1.0) {
|
||||
//DP sqrtcL = pow(cxL, 0.5);
|
||||
DP oneoversqrtcLN = 1.0/pow(cxL * N, 0.5);
|
||||
for (int a = 0; a < N; ++a) lambdaoc[a] = oneoversqrtcLN * PI * Ix2[a];
|
||||
|
||||
//for (int a = 0; a < N; ++a) lambdaoc[a] = sqrtcL * PI * Ix2[a]; // wrong values, correct scaling with c
|
||||
//for (int a = 0; a < N; ++a) lambdaoc[a] = PI * Ix2[a]/(cxL + 2.0 * N); // set to minimal distance lattice
|
||||
}
|
||||
|
||||
//cout << "Set free lambdaocs to: " << endl << lambdaoc << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Iterate_BAE (DP damping)
|
||||
{
|
||||
// does one step of simple iterations
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
Vect_DP dlambdaoc (0.0, N);
|
||||
|
||||
for (int j = 0; j < N; ++j) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < N; ++k) sumtheta += atan((lambdaoc[j] - lambdaoc[k]));
|
||||
sumtheta *= 2.0;
|
||||
|
||||
dlambdaoc[j] = damping * ((PI*Ix2[j] - sumtheta)/cxL - lambdaoc[j]);
|
||||
|
||||
}
|
||||
|
||||
diffsq = 0.0;
|
||||
//DP sumsq = 0.0;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
lambdaoc[i] += dlambdaoc[i];
|
||||
//sumsq += lambdaoc[i] * lambdaoc[i];
|
||||
//diffsq += dlambdaoc[i] * dlambdaoc[i];
|
||||
//if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i];
|
||||
//else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i];
|
||||
// Normalize the diffsq by the typical value of the rapidities:
|
||||
if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
|
||||
else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
|
||||
}
|
||||
diffsq /= DP(N);
|
||||
//diffsq /= sqrt(sumsq) * DP(N);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Iterate_BAE_S (DP damping)
|
||||
{
|
||||
// This is essentially Newton's method but only in one variable.
|
||||
// The logic is that the derivative of the LHS of the BE_j w/r to lambdaoc_j is much larger than with respect to lambdaoc_l with l != j.
|
||||
|
||||
Vect_DP dlambdaoc (0.0, N);
|
||||
|
||||
// Start by calculating S and dSdlambdaoc:
|
||||
for (int j = 0; j < N; ++j) {
|
||||
|
||||
S[j] = 0.0;
|
||||
for (int k = 0; k < N; ++k) S[j] += atan((lambdaoc[j] - lambdaoc[k]));
|
||||
S[j] *= 2.0/cxL;
|
||||
|
||||
dSdlambdaoc[j] = 0.0;
|
||||
for (int k = 0; k < N; ++k) dSdlambdaoc[j] += 1.0/((lambdaoc[j] - lambdaoc[k]) * (lambdaoc[j] - lambdaoc[k]) + 1.0);
|
||||
dSdlambdaoc[j] *= 2.0/(PI * cxL);
|
||||
|
||||
dlambdaoc[j] = (PI*Ix2[j]/cxL - S[j] + lambdaoc[j] * dSdlambdaoc[j])/(1.0 + dSdlambdaoc[j]) - lambdaoc[j];
|
||||
|
||||
}
|
||||
|
||||
diffsq = 0.0;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
lambdaoc[i] += damping * dlambdaoc[i];
|
||||
// Normalize the diffsq by the typical value of the rapidities:
|
||||
if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
|
||||
else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
|
||||
}
|
||||
diffsq /= DP(N);
|
||||
|
||||
iter_Newton++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Iterate_BAE_Newton (DP damping)
|
||||
{
|
||||
// does one step of a Newton method on the rapidities...
|
||||
|
||||
Vect_DP RHSBAE (0.0, N); // contains RHS of BAEs
|
||||
Vect_DP dlambdaoc (0.0, N); // contains delta lambdaoc computed from Newton's method
|
||||
SQMat_DP Gaudin (0.0, N);
|
||||
Vect_INT indx (N);
|
||||
DP sumtheta = 0.0;
|
||||
int atanintshift = 0; // for large |lambda|, use atan (lambda) = sgn(lambda) pi/2 - atan(1/lambda)
|
||||
DP lambdahere = 0.0;
|
||||
|
||||
// Compute the RHS of the BAEs:
|
||||
|
||||
for (int j = 0; j < N; ++j) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
atanintshift = 0;
|
||||
for (int k = 0; k < N; ++k)
|
||||
if (j != k) { // otherwise 0
|
||||
if (fabs(lambdahere = lambdaoc[j] - lambdaoc[k]) < 1.0) { // use straight atan
|
||||
sumtheta += atan(lambdahere);
|
||||
}
|
||||
else { // for large rapidities, use dual form of atan, extracting pi/2 factors
|
||||
atanintshift += sgn_DP(lambdahere);
|
||||
sumtheta -= atan(1.0/lambdahere);
|
||||
}
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
//cout << j << "\t" << Ix2[j] << "\t" << atanintshift << endl;
|
||||
|
||||
RHSBAE[j] = cxL * lambdaoc[j] + sumtheta - PI*(Ix2[j] - atanintshift);
|
||||
}
|
||||
|
||||
(*this).Build_Reduced_Gaudin_Matrix (Gaudin);
|
||||
|
||||
for (int j = 0; j < N; ++j) dlambdaoc[j] = - RHSBAE[j];
|
||||
|
||||
//cout << "dlambdaoc pre lubksb = " << dlambdaoc << endl;
|
||||
|
||||
DP d;
|
||||
ludcmp (Gaudin, indx, d);
|
||||
lubksb (Gaudin, indx, dlambdaoc);
|
||||
|
||||
//cout << "dlambdaoc post lubksb = " << dlambdaoc << endl;
|
||||
|
||||
bool ordering_changed = false;
|
||||
for (int j = 0; j < N-1; ++j) if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) ordering_changed = true;
|
||||
|
||||
// To prevent Newton from diverging, we limit the size of the rapidity changes.
|
||||
// The leftmost and rightmost rapidities can grow by one order of magnitude per iteration step.
|
||||
if (ordering_changed) { // We explicitly ensure that the ordering remains correct after the iteration step.
|
||||
bool ordering_still_changed = false;
|
||||
DP maxdlambdaoc = 0.0;
|
||||
do {
|
||||
ordering_still_changed = false;
|
||||
if (dlambdaoc[0] < 0.0 && fabs(dlambdaoc[0]) > (maxdlambdaoc = 10.0*JSC::max(fabs(lambdaoc[0]), fabs(lambdaoc[N-1]))))
|
||||
dlambdaoc[0] = -maxdlambdaoc;
|
||||
if (lambdaoc[0] + dlambdaoc[0] > lambdaoc[1] + dlambdaoc[1]) {
|
||||
dlambdaoc[0] = 0.25 * (lambdaoc[1] + dlambdaoc[1] - lambdaoc[0] ); // max quarter distance
|
||||
ordering_still_changed = true;
|
||||
//cout << "reason 1" << endl;
|
||||
}
|
||||
if (dlambdaoc[N-1] > 0.0 && fabs(dlambdaoc[N-1]) > (maxdlambdaoc = 10.0*JSC::max(fabs(lambdaoc[0]), fabs(lambdaoc[N-1]))))
|
||||
dlambdaoc[N-1] = maxdlambdaoc;
|
||||
if (lambdaoc[N-1] + dlambdaoc[N-1] < lambdaoc[N-2] + dlambdaoc[N-2]) {
|
||||
dlambdaoc[N-1] = 0.25 * (lambdaoc[N-2] + dlambdaoc[N-2] - lambdaoc[N-1]);
|
||||
ordering_still_changed = true;
|
||||
//cout << "reason 2" << endl;
|
||||
}
|
||||
for (int j = 1; j < N-1; ++j) {
|
||||
if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) {
|
||||
dlambdaoc[j] = 0.25 * (lambdaoc[j+1] + dlambdaoc[j+1] - lambdaoc[j]);
|
||||
ordering_still_changed = true;
|
||||
//cout << "reason 3" << endl;
|
||||
}
|
||||
if (lambdaoc[j] + dlambdaoc[j] < lambdaoc[j-1] + dlambdaoc[j-1]) {
|
||||
dlambdaoc[j] = 0.25 * (lambdaoc[j-1] + dlambdaoc[j-1] - lambdaoc[j]);
|
||||
ordering_still_changed = true;
|
||||
//cout << "reason 4" << endl;
|
||||
}
|
||||
}
|
||||
} while (ordering_still_changed);
|
||||
}
|
||||
|
||||
//if (ordering_changed) cout << "dlambdaoc post checking = " << dlambdaoc << endl;
|
||||
|
||||
/*
|
||||
bool orderingchanged = false;
|
||||
//bool dlambdaexceedsmaxrapdiff = false;
|
||||
DP damping_to_use = damping;
|
||||
for (int j = 0; j < N-1; ++j) {
|
||||
if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) // unacceptable, order changed!
|
||||
orderingchanged = true;
|
||||
// We must damp the dlambda such that the ordering is unchanged:
|
||||
// the condition is lambdaoc[j] + damping*dlambdaoc[j] < lambdaoc[j+1] + damping*dlambdaoc[j+1]
|
||||
damping_to_use = JSC::min(damping_to_use, 0.5 * (lambdaoc[j+1] - lambdaoc[j])/(dlambdaoc[j] - dlambdaoc[j+1]));
|
||||
}
|
||||
*/
|
||||
//for (int j = 0; j < N; ++j)
|
||||
//if (fabs(dlambdaoc[j]) > maxrapdiff) dlambdaexceedsmaxrapdiff = true;
|
||||
/*
|
||||
// The dlambdaoc must be smaller than the distance to neighbouring rapidities:
|
||||
// If any dlambdaoc is greater than half the distance, set all to half the previous distance:
|
||||
if (orderingchanged || dlambdaexceedsmaxrapdiff) {
|
||||
if (dlambdaoc[0] > 0.0) dlambdaoc[0] = 0.25 * (lambdaoc[1] - lambdaoc[0]);
|
||||
//else dlambdaoc[0] = 0.25 * (lambdaoc[0] - lambdaoc[1]);
|
||||
else dlambdaoc[0] = -fabs(lambdaoc[0]); // strictly limit the growth of lambdaoc[0]
|
||||
//if (dlambdaoc[N-1] > 0.0) dlambdaoc[N-1] = 0.25 * (lambdaoc[N-1] - lambdaoc[N-2]);
|
||||
if (dlambdaoc[N-1] > 0.0) dlambdaoc[N-1] = fabs(lambdaoc[N-1]); // strictly limit the growth of lambdaoc[N-1]
|
||||
else dlambdaoc[N-1] = 0.25 * (lambdaoc[N-2] - lambdaoc[N-1]);
|
||||
for (int j = 1; j < N-1; ++j) {
|
||||
if (dlambdaoc[j] > 0.0) dlambdaoc[j] = 0.25 * (lambdaoc[j+1] - lambdaoc[j]);
|
||||
if (dlambdaoc[j] < 0.0) dlambdaoc[j] = 0.25 * (lambdaoc[j-1] - lambdaoc[j]);
|
||||
}
|
||||
//cout << "Corrected dlambdaoc = " << dlambdaoc << endl;
|
||||
}
|
||||
*/
|
||||
diffsq = 0.0;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
//diffsq += dlambdaoc[i] * dlambdaoc[i];
|
||||
// Normalize the diffsq by the typical value of the rapidities:
|
||||
if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
|
||||
else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
|
||||
}
|
||||
diffsq /= DP(N);
|
||||
|
||||
if (ordering_changed) diffsq = 1.0; // reset if Newton wanted to change ordering
|
||||
|
||||
for (int j = 0; j < N; ++j) lambdaoc[j] += damping * dlambdaoc[j];
|
||||
//for (int j = 0; j < N; ++j) lambdaoc[j] += damping_to_use * dlambdaoc[j];
|
||||
|
||||
iter_Newton++;
|
||||
|
||||
// if we've converged, calculate the norm here, since the work has been done...
|
||||
|
||||
//if (diffsq < prec && !orderingchanged && !dlambdaexceedsmaxrapdiff) {
|
||||
if (diffsq < prec && !ordering_changed) {
|
||||
|
||||
lnnorm = 0.0;
|
||||
for (int j = 0; j < N; j++) lnnorm += log(fabs(Gaudin[j][j]));
|
||||
|
||||
// Add the pieces outside of Gaudin determinant
|
||||
for (int j = 0; j < N - 1; ++j) for (int k = j+1; k < N; ++k) lnnorm += log(1.0 + 1.0/pow(lambdaoc[j] - lambdaoc[k], 2.0));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Compute_Energy()
|
||||
{
|
||||
E = 0.0;
|
||||
for (int j = 0; j < N; ++j) E += lambdaoc[j] * lambdaoc[j];
|
||||
E *= c_int * c_int;
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Compute_Momentum()
|
||||
{
|
||||
iK = 0;
|
||||
for (int j = 0; j < N; ++j) {
|
||||
//cout << j << "\t" << iK << "\t" << Ix2[j] << endl;
|
||||
iK += Ix2[j];
|
||||
}
|
||||
if (iK % 2) {
|
||||
cout << Ix2 << endl;
|
||||
cout << iK << "\t" << iK % 2 << endl;
|
||||
JSCerror("Sum of Ix2 is not even: inconsistency.");
|
||||
}
|
||||
iK /= 2; // sum of Ix2 is guaranteed even.
|
||||
|
||||
K = 2.0 * iK * PI/L;
|
||||
}
|
||||
|
||||
DP LiebLin_Bethe_State::Kernel (int a, int b)
|
||||
{
|
||||
return(2.0/(pow(lambdaoc[a] - lambdaoc[b], 2.0) + 1.0));
|
||||
}
|
||||
|
||||
DP LiebLin_Bethe_State::Kernel (DP lambdaoc_ref)
|
||||
{
|
||||
return(2.0/(lambdaoc_ref * lambdaoc_ref + 1.0));
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<DP>& Gaudin_Red)
|
||||
{
|
||||
|
||||
if (Gaudin_Red.size() != N) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
|
||||
DP sum_Kernel = 0.0;
|
||||
|
||||
for (int j = 0; j < N; ++j)
|
||||
for (int k = 0; k < N; ++k) {
|
||||
|
||||
if (j == k) {
|
||||
sum_Kernel = 0.0;
|
||||
for (int kp = 0; kp < N; ++kp) if (j != kp) sum_Kernel += Kernel (lambdaoc[j] - lambdaoc[kp]);
|
||||
Gaudin_Red[j][k] = cxL + sum_Kernel;
|
||||
}
|
||||
|
||||
else Gaudin_Red[j][k] = - Kernel (lambdaoc[j] - lambdaoc[k]);
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Build_Reduced_BEC_Quench_Gaudin_Matrix (SQMat<DP>& Gaudin_Red)
|
||||
{
|
||||
// Passing a matrix of dimension N/2
|
||||
|
||||
if (N % 2 != 0) JSCerror("Choose a state with even numer of particles please");
|
||||
|
||||
// Check Parity invariant
|
||||
|
||||
bool ck = true;
|
||||
|
||||
for (int j = 0; j < N/2; ++j){ if(Ix2[j] != - Ix2[N-j-1]) ck = false;}
|
||||
|
||||
if (!ck) JSCerror("Choose a parity invariant state please");
|
||||
|
||||
if (Gaudin_Red.size() != N/2) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
|
||||
DP sum_Kernel = 0.0;
|
||||
|
||||
for (int j = 0; j < N/2; ++j)
|
||||
for (int k = 0; k < N/2; ++k) {
|
||||
|
||||
if (j == k) {
|
||||
sum_Kernel = 0.0;
|
||||
for (int kp = N/2; kp < N; ++kp) if (j + N/2 != kp) sum_Kernel += Kernel (lambdaoc[j+N/2] - lambdaoc[kp]) + Kernel (lambdaoc[j+N/2] + lambdaoc[kp]);
|
||||
Gaudin_Red[j][k] = cxL + sum_Kernel;
|
||||
}
|
||||
|
||||
else Gaudin_Red[j][k] = - (Kernel (lambdaoc[j+ N/2] - lambdaoc[k+ N/2]) + Kernel (lambdaoc[j+ N/2] + lambdaoc[k+ N/2]) );
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void LiebLin_Bethe_State::Annihilate_ph_pair (int ipart, int ihole, const Vect<int>& OriginStateIx2)
|
||||
{
|
||||
// This function changes the Ix2 of a given state by annihilating a particle and hole
|
||||
// pair specified by ipart and ihole (counting from the left, starting with index 0).
|
||||
|
||||
//cout << "Annihilating ipart " << ipart << " and ihole " << ihole << " of state with label " << (*this).label << endl;
|
||||
|
||||
State_Label_Data currentdata = Read_State_Label ((*this).label, OriginStateIx2);
|
||||
//cout << "current Ix2old " << currentdata.Ix2old[0] << endl;
|
||||
//cout << "current Ix2exc " << currentdata.Ix2exc[0] << endl;
|
||||
|
||||
if (ipart >= currentdata.nexc[0]) JSCerror("Particle label too large in LiebLin_Bethe_State::Annihilate_ph_pair.");
|
||||
if (ihole >= currentdata.nexc[0]) JSCerror("Hole label too large in LiebLin_Bethe_State::Annihilate_ph_pair.");
|
||||
|
||||
// Simply remove the given pair:
|
||||
Vect<int> type_new = currentdata.type;
|
||||
Vect<int> M_new = currentdata.M;
|
||||
Vect<int> nexc_new = currentdata.nexc;
|
||||
nexc_new[0] -= 1; // we drill one more particle-hole pair at level 0
|
||||
int ntypespresent = 1; // only one type for LiebLin
|
||||
Vect<Vect<int> > Ix2old_new(ntypespresent);
|
||||
Vect<Vect<int> > Ix2exc_new(ntypespresent);
|
||||
for (int it = 0; it < ntypespresent; ++it) Ix2old_new[it] = Vect<int>(JSC::max(nexc_new[it],1));
|
||||
for (int it = 0; it < ntypespresent; ++it) Ix2exc_new[it] = Vect<int>(JSC::max(nexc_new[it],1));
|
||||
|
||||
// Copy earlier data in, leaving out ipart and ihole:
|
||||
for (int it = 0; it < ntypespresent; ++it) {
|
||||
for (int i = 0; i < nexc_new[it]; ++i) {
|
||||
Ix2old_new[it][i] = currentdata.Ix2old[it][i + (i >= ihole)];
|
||||
Ix2exc_new[it][i] = currentdata.Ix2exc[it][i + (i >= ipart)];
|
||||
}
|
||||
}
|
||||
//cout << "Ix2old_new " << Ix2old_new[0] << endl;
|
||||
//cout << "Ix2exc_new " << Ix2exc_new[0] << endl;
|
||||
|
||||
State_Label_Data newdata (type_new, M_new, nexc_new, Ix2old_new, Ix2exc_new);
|
||||
|
||||
(*this).Set_to_Label (Return_State_Label(newdata, OriginStateIx2));
|
||||
|
||||
//cout << "Obtained label " << (*this).label << endl;
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Parity_Flip ()
|
||||
{
|
||||
// For simplicity, we don't redo base_id, type_id, id.
|
||||
Vect_INT Ix2buff = Ix2;
|
||||
Vect_DP lambdaocbuff = lambdaoc;
|
||||
for (int i = 0; i < N; ++i) Ix2[i] = -Ix2buff[N - 1 - i];
|
||||
for (int i = 0; i < N; ++i) lambdaoc[i] = -lambdaocbuff[N - 1 - i];
|
||||
iK = -iK;
|
||||
K = -K;
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& s, const LiebLin_Bethe_State& state)
|
||||
{
|
||||
s << endl << "******** State for c = " << state.c_int << " L = " << state.L << " N = " << state.N
|
||||
<< " with label " << state.label << " ********" << endl;
|
||||
s << "Ix2:" << endl;
|
||||
for (int j = 0; j < state.N; ++j) s << state.Ix2[j] << " ";
|
||||
s << endl << "lambdaocs:" << endl;
|
||||
for (int j = 0; j < state.N; ++j) s << state.lambdaoc[j] << " ";
|
||||
s << endl << "conv = " << state.conv << " iter_Newton = " << state.iter_Newton << endl;
|
||||
s << "E = " << state.E << " iK = " << state.iK << " K = " << state.K << " lnnorm = " << state.lnnorm << endl;
|
||||
|
||||
return(s);
|
||||
}
|
||||
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,38 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/LIEBLIN/LiebLin_Chem_Pot.cc
|
||||
|
||||
Purpose: calculates the chemical potential.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
DP Chemical_Potential (LiebLin_Bethe_State& RefState)
|
||||
{
|
||||
// RefState is used here to provide the c_int, L and N parameters.
|
||||
|
||||
LiebLin_Bethe_State Nplus1State(RefState.c_int, RefState.L, RefState.N + 1);
|
||||
//LiebLin_Bethe_State NState(RefState.c_int, RefState.L, RefState.N);
|
||||
LiebLin_Bethe_State Nmin1State(RefState.c_int, RefState.L, RefState.N - 1);
|
||||
|
||||
Nplus1State.Compute_All(true);
|
||||
//NState.Compute_All(true);
|
||||
Nmin1State.Compute_All(true);
|
||||
|
||||
//return(NState.E - Nmin1State.E);
|
||||
return(0.5 * (Nplus1State.E - Nmin1State.E));
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,184 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/LIEBLIN/LiebLin_Matrix_Element_Contrib.cc
|
||||
|
||||
Purpose: handles the generic call for a Lieb-Liniger matrix element contribution.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, LiebLin_Bethe_State& LeftState,
|
||||
// LiebLin_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState,
|
||||
// LiebLin_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState,
|
||||
LiebLin_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile)
|
||||
{
|
||||
// This function prints the matrix element information to the fstream,
|
||||
// and returns a weighed `data_value' to be multiplied by sumrule_factor,
|
||||
// to determine if scanning along this thread should be continued.
|
||||
|
||||
bool fixed_iK = (iKmin == iKmax);
|
||||
|
||||
// Identify which matrix element is needed from the number of particles in Left and Right states:
|
||||
DP ME = 0.0;
|
||||
complex<DP> ME_CX = 0.0;
|
||||
|
||||
if (whichDSF == 'Z')
|
||||
ME = LeftState.E - RefState.E;
|
||||
else if (whichDSF == 'd' || whichDSF == '1')
|
||||
ME = real(exp(ln_Density_ME (LeftState, RefState)));
|
||||
else if (whichDSF == 'o')
|
||||
ME = real(exp(ln_Psi_ME (LeftState, RefState)));
|
||||
else if (whichDSF == 'g')
|
||||
ME = real(exp(ln_Psi_ME (RefState, LeftState)));
|
||||
else if (whichDSF == 'q') // geometrical quench
|
||||
//ME_CX = (LiebLin_Twisted_ln_Overlap(1.0, RefState.lambdaoc, RefState.lnnorm, LeftState));
|
||||
//ME_CX = (LiebLin_ln_Overlap(RefState.lambdaoc, RefState.lnnorm, LeftState));
|
||||
ME_CX = LiebLin_ln_Overlap(LeftState.lambdaoc, LeftState.lnnorm, RefState);
|
||||
else if (whichDSF == 'B') { // BEC to finite c quench: g2(x=0)
|
||||
//ME_CX = exp(ln_Overlap_with_BEC (LeftState)); // overlap part
|
||||
ME_CX = exp(ln_Overlap_with_BEC (LeftState) - ln_Overlap_with_BEC (RefState)); // overlap part, relative to saddle-point state
|
||||
ME = real(exp(ln_g2_ME (RefState, LeftState))); // matrix element part
|
||||
// The product is ME_CX * ME = e^{-\delta S_e} \langle \rho_{sp} | g2 (x=0) | \rho_{sp} + e \rangle
|
||||
// and is the first half of the t-dep expectation value formula coming from the Quench Action formalism
|
||||
}
|
||||
else if (whichDSF == 'C') { // BEC to finite c quench: overlap
|
||||
ME_CX = exp(2.0* ln_Overlap_with_BEC (LeftState)); // overlap sq part
|
||||
ME = 0.0;
|
||||
}
|
||||
else JSCerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
|
||||
|
||||
if (is_nan(ME)) ME = (whichDSF == 'Z') ? 1.0e+200 : 0.0;
|
||||
if (is_nan(norm(ME_CX))) ME_CX = -100.0;
|
||||
|
||||
|
||||
// Print information to fstream:
|
||||
if (LeftState.iK - RefState.iK >= iKmin && LeftState.iK - RefState.iK <= iKmax) {
|
||||
if (whichDSF == 'Z') {
|
||||
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
|
||||
<< LeftState.iK - RefState.iK
|
||||
//<< "\t" << LeftState.conv
|
||||
<< 0 << "\t" // This is the deviation, here always 0
|
||||
<< "\t" << LeftState.label;
|
||||
}
|
||||
else if (whichDSF == 'q') {
|
||||
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
|
||||
<< LeftState.iK - RefState.iK << "\t"
|
||||
<< real(ME_CX) << "\t" << imag(ME_CX) - twoPI * int(imag(ME_CX)/twoPI + 1.0e-10) << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< 0 << "\t" // This is the deviation, here always 0
|
||||
<< LeftState.label;
|
||||
}
|
||||
else if (whichDSF == '1') {
|
||||
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
|
||||
<< LeftState.iK - RefState.iK << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< 0 << "\t" // This is the deviation, here always 0
|
||||
<< LeftState.label;
|
||||
DAT_outfile << "\t" << Momentum_Right_Excitations(LeftState) << "\t" << Momentum_Left_Excitations(LeftState);
|
||||
//cout << Momentum_Right_Excitations(LeftState) << "\t" << Momentum_Left_Excitations(LeftState);
|
||||
}
|
||||
else if (whichDSF == 'B') { // BEC to finite c > 0 quench; g2 (x=0)
|
||||
if (fabs(real(ME_CX) * ME) > 1.0e-100)
|
||||
DAT_outfile << endl << LeftState.E - RefState.E << "\t"
|
||||
<< LeftState.iK - RefState.iK << "\t"
|
||||
<< real(ME_CX) << "\t" // the overlap is always real
|
||||
<< ME << "\t"
|
||||
//<< 0 << "\t" // This is the deviation, here always 0 // omit this here
|
||||
<< LeftState.label;
|
||||
}
|
||||
else if (whichDSF == 'C') { // BEC to finite c, overlap sq
|
||||
if (fabs(real(ME_CX)) > 1.0e-100)
|
||||
DAT_outfile << endl << LeftState.E - RefState.E << "\t"
|
||||
<< LeftState.iK - RefState.iK << "\t"
|
||||
<< real(ME_CX) << "\t" // the overlap is always real
|
||||
<< ME << "\t"
|
||||
//<< 0 << "\t" // This is the deviation, here always 0 // omit this here
|
||||
<< LeftState.label;
|
||||
}
|
||||
else {
|
||||
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
|
||||
<< LeftState.iK - RefState.iK << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< 0 << "\t" // This is the deviation, here always 0
|
||||
<< LeftState.label;
|
||||
}
|
||||
} // if iKmin <= iK <= iKmax
|
||||
|
||||
// Calculate and return the data_value:
|
||||
DP data_value = ME * ME;
|
||||
if (whichDSF == 'Z') // use 1/(1 + omega)
|
||||
data_value = 1.0/(1.0 + LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot);
|
||||
else if (whichDSF == 'd' || whichDSF == '1') {
|
||||
if (fixed_iK)
|
||||
/*
|
||||
// use omega * MEsq/iK^2
|
||||
//data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot)
|
||||
// MEsq/JSC::max(1, (LeftState.iK - RefState.iK) * (LeftState.iK - RefState.iK))
|
||||
//: 0.0;
|
||||
*/
|
||||
// Careful: use fabs(E) since this must also work with Tgt0 or arbitrary RefState DEPRECATED ++G_1, USE abs_data_value
|
||||
data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
|
||||
else if (!fixed_iK) // use ME if momentum in fundamental window -iK_UL <= iK <= iK_UL
|
||||
//data_value = abs(LeftState.iK - RefState.iK) <= RefState.Tableau[0].Ncols ? // this last nr is iK_UL
|
||||
//MEsq : 0.0;
|
||||
//data_value = (LeftState.iK - RefState.iK == 0 ? 1.0 : 2.0) * MEsq;
|
||||
//data_value = ME * ME;
|
||||
// use omega * MEsq/iK^2
|
||||
// Careful: use fabs(E) since this must also work with Tgt0 or arbitrary RefState DEPRECATED ++G_1, USE abs_data_value
|
||||
data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME/JSC::max(1, (LeftState.iK - RefState.iK) * (LeftState.iK - RefState.iK));
|
||||
}
|
||||
else if (whichDSF == 'g' || whichDSF == 'o') {
|
||||
if (fixed_iK)
|
||||
/*
|
||||
// use omega * MEsq/((k^2 - mu + 4 c N/L)/L)
|
||||
data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot)
|
||||
* MEsq/((((LeftState.K - RefState.K) * (LeftState.K - RefState.K) - Chem_Pot) + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L)
|
||||
: 0.0;
|
||||
*/
|
||||
// Careful: use fabs(E) since this must also work with Tgt0 or arbitrary RefState
|
||||
data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
|
||||
else if (!fixed_iK) { // simply use MEsq if momentum in fundamental window -iK_UL <= iK <= iK_UL
|
||||
//data_value = abs(LeftState.iK - RefState.iK) <= RefState.Tableau[0].Ncols ? // this last nr is iK_UL
|
||||
//MEsq : 0.0;
|
||||
//data_value = (LeftState.iK - RefState.iK == 0 ? 1.0 : 2.0) * MEsq;
|
||||
data_value = ME * ME;
|
||||
//data_value = fabs(LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
|
||||
// In the case of whichDSF == 'o', the state with label (N-1)_0_ gives zero data_value. Force to 1.
|
||||
//if (whichDSF == 'o' && fabs(LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) < 1.0e-10) data_value = 1.0;
|
||||
}
|
||||
}
|
||||
//else if (whichDSF == 'o')
|
||||
//data_value = abs(LeftState.iK - RefState.iK) <= RefState.Tableau[0].Ncols ? // this last nr is iK_UL
|
||||
//MEsq : 0.0;
|
||||
else if (whichDSF == 'q')
|
||||
data_value = exp(2.0 * real(ME_CX));
|
||||
else if (whichDSF == 'B')
|
||||
data_value = abs(ME_CX * ME)/(1.0 + sqrt(fabs(LeftState.E - RefState.E)));
|
||||
else if (whichDSF == 'C')
|
||||
data_value = abs(ME_CX);
|
||||
|
||||
if (whichDSF == '1') // hard cutoff for nr, nl when calculating exponents
|
||||
if (Momentum_Right_Excitations(LeftState) >= 30 || Momentum_Left_Excitations(LeftState) >= 30)
|
||||
data_value = 0.0;
|
||||
|
||||
return(data_value);
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,929 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_State_Ensemble.cc
|
||||
|
||||
Purpose: State ensembles for Lieb-Liniger
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// Constructors:
|
||||
|
||||
LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble ()
|
||||
: nstates(0), state(Vect<LiebLin_Bethe_State>(1)), weight(0.0, 1)
|
||||
{
|
||||
}
|
||||
|
||||
LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (const LiebLin_Bethe_State& RefState, int nstates_req)
|
||||
: nstates(nstates_req), state(Vect<LiebLin_Bethe_State>(RefState, nstates_req)), weight(1.0/nstates_req, nstates_req)
|
||||
{
|
||||
}
|
||||
/*
|
||||
LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (const LiebLin_Bethe_State& RefState, int nstates_req, const Vect<DP>& weight_ref)
|
||||
: nstates(nstates_req), state(Vect<LiebLin_Bethe_State>(RefState, nstates_req)), weight(weight_ref)
|
||||
{
|
||||
if (weight_ref.size() != nstates_req) JSCerror("Incompatible vector size in LiebLin_Diagonal_State_Ensemble constructor.");
|
||||
}
|
||||
*/
|
||||
|
||||
// Recursively go through all arbitrary-order type 2 descendents
|
||||
void Generate_type_2_descendents (LiebLin_Bethe_State& ActualState, int* ndesc_ptr, const LiebLin_Bethe_State& OriginState)
|
||||
{
|
||||
int type_required = 3;
|
||||
Vect<string> desc_label = Descendents (ActualState, OriginState, type_required);
|
||||
|
||||
if (desc_label.size() > 0) { // follow down recursively
|
||||
LiebLin_Bethe_State ActualState_here = ActualState;
|
||||
for (int idesc = 0; idesc < desc_label.size(); ++idesc) {
|
||||
ActualState_here.Set_to_Label (desc_label[idesc], OriginState.Ix2);
|
||||
// output data:
|
||||
cout << *ndesc_ptr << "\t" << desc_label[idesc] << endl;
|
||||
cout << "origin: " << OriginState.Ix2 << endl;
|
||||
cout << "shiftd: " << ActualState_here.Ix2 << endl;
|
||||
ActualState_here.Compute_All(false);
|
||||
cout << "\t\t\t\t\t\t" << ActualState.E - OriginState.E << endl;
|
||||
*ndesc_ptr += 1;
|
||||
Generate_type_2_descendents (ActualState_here, ndesc_ptr, OriginState);
|
||||
|
||||
// do them mod st:
|
||||
idesc += 6;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho, int nstates_req)
|
||||
//: nstates(nstates_req)
|
||||
LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho)
|
||||
{
|
||||
//version with 4 states in ensemble
|
||||
|
||||
Root_Density x(rho.Npts, rho.lambdamax);
|
||||
|
||||
for(int ix=0; ix<x.Npts; ++ix) {
|
||||
x.value[ix] = x.lambda[ix];
|
||||
for( int ip=0; ip<rho.Npts; ++ip) {
|
||||
x.value[ix] += 2.0 * rho.value[ip] * rho.dlambda[ip] * atan ((x.lambda[ix] - rho.lambda[ip])/c_int);
|
||||
}
|
||||
x.value[ix] /= 2.0*PI; //normalization
|
||||
|
||||
//cout << x.lambda[ix] << "\t" << x.value[ix] << "\t" << rho.lambda[ix] "\t" << rho.value[ix] <<endl;
|
||||
}
|
||||
|
||||
// Now carry on as per Discretized_LiebLin_Bethe_State:
|
||||
// Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
|
||||
DP integral = 0.0;
|
||||
DP integral_prev = 0.0;
|
||||
int Nfound = 0;
|
||||
Vect<DP> Ix2_found(0.0, N);
|
||||
int Ix2_left, Ix2_right;
|
||||
Vect<int> Ix2(N);
|
||||
|
||||
|
||||
LiebLin_Bethe_State rhostate(c_int, N, L);
|
||||
|
||||
nstates = 4;
|
||||
state = Vect<LiebLin_Bethe_State>(rhostate, nstates);
|
||||
weight = Vect<DP>(nstates);
|
||||
weight[0] = 1.0/nstates;
|
||||
weight[1] = 1.0/nstates;
|
||||
weight[2] = 1.0/nstates;
|
||||
weight[3] = 1.0/nstates;
|
||||
|
||||
int n_moves = 0;
|
||||
bool change = true;
|
||||
|
||||
for (int i = 0; i < rho.Npts; ++i) {
|
||||
integral_prev = integral;
|
||||
integral += L * rho.value[i] * rho.dlambda[i];
|
||||
//cout << x.value[i] << "\t" << integral << endl;
|
||||
if (integral > Nfound + 0.5) {
|
||||
// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
|
||||
if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
|
||||
JSCerror("The distribution of particles is too discontinous for discretisation");
|
||||
}
|
||||
|
||||
else {
|
||||
// few variables to clarify the computations, they do not need to be vectors, not used outside this loop
|
||||
//Ix2_found[Nfound] = 2.0 * L * (x.value[i] * (integral - Nfound - 0.5) + x.value[i-1] * (Nfound + 0.5 - integral_prev))/(integral - integral_prev);
|
||||
Ix2_found[Nfound] = 2.0 * L * x.Return_Value(rho.lambda[i]);
|
||||
|
||||
Ix2_left = floor(Ix2_found[Nfound]);
|
||||
Ix2_left -= (Ix2_left + N + 1)%2 ? 1 : 0; //adjust parity
|
||||
|
||||
Ix2_right = ceil(Ix2_found[Nfound]);
|
||||
Ix2_right += (Ix2_right + N + 1)%2 ? 1 : 0; //adjust parity
|
||||
|
||||
int Ix2_in = (Ix2_found[Nfound] > 0 ? Ix2_left : Ix2_right);
|
||||
int Ix2_out = (Ix2_found[Nfound] > 0 ? Ix2_right : Ix2_left);
|
||||
cout << rho.lambda[i] << "\t" << x.Return_Value(rho.lambda[i]) << "\t" << Ix2_found[Nfound] << endl;
|
||||
|
||||
//choose the saddle point state and remember the uncertain choices
|
||||
if(Ix2_found[Nfound] - Ix2_left < 0.5) {
|
||||
state[0].Ix2[Nfound] = Ix2_left;
|
||||
state[1].Ix2[Nfound] = Ix2_left;
|
||||
state[2].Ix2[Nfound] = Ix2_left;
|
||||
state[3].Ix2[Nfound] = Ix2_left;
|
||||
}
|
||||
else if (Ix2_right - Ix2_found[Nfound] < 0.5) {
|
||||
state[0].Ix2[Nfound] = Ix2_right;
|
||||
state[1].Ix2[Nfound] = Ix2_right;
|
||||
state[2].Ix2[Nfound] = Ix2_right;
|
||||
state[3].Ix2[Nfound] = Ix2_right;
|
||||
}
|
||||
else { //it's a kind of magic: the zeroth goes in whle the first goes out, the second goes left if the third goes right
|
||||
state[0].Ix2[Nfound] = Ix2_in;
|
||||
state[1].Ix2[Nfound] = Ix2_out;
|
||||
state[2+change].Ix2[Nfound] = Ix2_left;
|
||||
state[2+!change].Ix2[Nfound] = Ix2_right;
|
||||
change = !change;
|
||||
++n_moves;
|
||||
}
|
||||
Nfound++;
|
||||
}
|
||||
}
|
||||
//cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
//fix state[3] and state[4]
|
||||
for(int i=0; i<N-1; ++i) {
|
||||
if(state[2].Ix2[i] == state[2].Ix2[i+1]) {
|
||||
if(state[2].Ix2[i] != state[2].Ix2[i-1] + 2) state[2].Ix2[i] -= 2;
|
||||
else state[2].Ix2[i+1] += 2;
|
||||
}
|
||||
if(state[3].Ix2[i] == state[3].Ix2[i+1]) {
|
||||
if(state[3].Ix2[i] != state[3].Ix2[i-1] + 2) state[3].Ix2[i] -= 2;
|
||||
else state[3].Ix2[i+1] += 2;
|
||||
}
|
||||
}
|
||||
|
||||
bool all_Diff = true;
|
||||
//check that all 'ns' states are different, we assume that Ix2 are ordered
|
||||
for(int i=0; i<nstates; ++i)
|
||||
for(int j=i+1; j<nstates; ++j) {
|
||||
if(state[i].Ix2 == state[j].Ix2)
|
||||
all_Diff = false;
|
||||
}
|
||||
|
||||
if(!all_Diff) {
|
||||
//check if the first two states are different
|
||||
if(state[0].Ix2 == state[1].Ix2)
|
||||
JSCerror("Cannot create 4 (nor 2) different states in LiebLin_Diagonal_State_Ensemble. Consider increasing system size");
|
||||
else {
|
||||
nstates = 2;
|
||||
weight[0] = 0.5;
|
||||
weight[1] = 0.5;
|
||||
}
|
||||
}
|
||||
//set the weights accordingly to the distance between the states.
|
||||
// int n_moves_2 = 0, n_moves_3 = 0;
|
||||
// for(int i=0; i < N; ++i) {
|
||||
// if (!state[0].Ix2.is_in(state[2].Ix2[i])) ++n_moves_2;
|
||||
// if (!state[0].Ix2.is_in(state[3].Ix2[i])) ++n_moves_3;
|
||||
// }
|
||||
//
|
||||
// n_moves_2 = min(n_moves_2, n_moves - n_moves_2);
|
||||
// n_moves_3 = min(n_moves_3, n_moves - n_moves_3);
|
||||
//
|
||||
// weight[2] *= 2.0*n_moves_2/n_moves;
|
||||
// weight[3] *= 2.0*n_moves_3/n_moves;
|
||||
//
|
||||
// DP sum_weight = weight[0] + weight[1] + weight[2] + weight[3];
|
||||
|
||||
for(int i=0; i<nstates; ++i) {
|
||||
//weight[i] /= sum_weight;
|
||||
state[i].Set_Label_from_Ix2(state[0].Ix2);
|
||||
state[i].Compute_All(true);
|
||||
}
|
||||
|
||||
|
||||
cout << weight[0] << "\t" << state[0].Ix2 << endl << weight[0] << "\t" << state[1].Ix2 << endl;// << state[2].Ix2 << endl << state[3].Ix2 << endl;
|
||||
|
||||
return;
|
||||
|
||||
|
||||
//old working version but not enough to saturate +fsumrule
|
||||
/*
|
||||
Root_Density x = rho;
|
||||
for(int ix=0; ix<x.Npts; ++ix) {
|
||||
x.value[ix] = x.lambda[ix];
|
||||
for( int ip=0; ip<rho.Npts; ++ip) {
|
||||
x.value[ix] += 2.0 * rho.value[ip] * rho.dlambda[ip] * atan ((x.lambda[ix] - rho.lambda[ip])/c_int);
|
||||
}
|
||||
x.value[ix] /= 2.0*PI; //normalization
|
||||
}
|
||||
|
||||
// Now carry on as per Discretized_LiebLin_Bethe_State:
|
||||
// Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
|
||||
DP integral = 0.0;
|
||||
DP integral_prev = 0.0;
|
||||
int Nfound = 0;
|
||||
Vect<DP> Ix2_found(0.0, N);
|
||||
int Ix2_left, Ix2_right;
|
||||
Vect<int> Ix2(N);
|
||||
Vect<int> Ix2_uncertain(0, N);
|
||||
Vect<int> index_uncertain(0, N);
|
||||
int n_uncertain = 0, n_states_raw = 1;
|
||||
|
||||
for (int i = 0; i < rho.Npts; ++i) {
|
||||
integral_prev = integral;
|
||||
integral += L * rho.value[i] * rho.dlambda[i];
|
||||
//cout << x.value[i] << "\t" << integral << endl;
|
||||
if (integral > Nfound + 0.5) {
|
||||
// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
|
||||
if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
|
||||
JSCerror("The distribution of particles is too discontinous for discretisation");
|
||||
}
|
||||
|
||||
else {
|
||||
// few variables to clarify the computations, they do not need to be vectors, not used outside this loop
|
||||
Ix2_found[Nfound] = 2.0 * L * (x.value[i] * (integral - Nfound - 0.5) + x.value[i-1] * (Nfound + 0.5 - integral_prev))/(integral - integral_prev);
|
||||
|
||||
Ix2_left = floor(Ix2_found[Nfound]);
|
||||
Ix2_left -= (Ix2_left + N + 1)%2 ? 1 : 0; //adjust parity
|
||||
|
||||
Ix2_right = ceil(Ix2_found[Nfound]);
|
||||
Ix2_right += (Ix2_right + N + 1)%2 ? 1 : 0; //adjust parity
|
||||
|
||||
//cout << Ix2_found[Nfound] << "\t";
|
||||
|
||||
//choose the saddle point state and remember the uncertain choices
|
||||
if(Ix2_found[Nfound] - Ix2_left < 1) {
|
||||
Ix2[Nfound] = Ix2_left;
|
||||
if(Ix2_found[Nfound] - Ix2_left > 0.75) {
|
||||
Ix2_uncertain[n_uncertain] = -1;
|
||||
index_uncertain[n_uncertain] = Nfound;
|
||||
++n_uncertain;
|
||||
n_states_raw *= 2;
|
||||
}
|
||||
}
|
||||
else if (Ix2_right - Ix2_found[Nfound] < 1) {
|
||||
Ix2[Nfound] = Ix2_right;
|
||||
if(Ix2_right - Ix2_found[Nfound] > 0.75) {
|
||||
Ix2_uncertain[n_uncertain] = 1;
|
||||
index_uncertain[n_uncertain] = Nfound;
|
||||
++n_uncertain;
|
||||
n_states_raw *= 2;
|
||||
}
|
||||
}
|
||||
else JSCerror("Cannot deduce a quantum number from x(lambda)");
|
||||
Nfound++;
|
||||
}
|
||||
}
|
||||
//cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
//cout << Ix2 << endl;
|
||||
|
||||
// create ensamble of states and compute its weights with respect to exact Ix2 saddle point
|
||||
Vect<Vect<int> > Ix2states(Ix2, n_states_raw);
|
||||
Vect<DP> Ix2weight(0.0, n_states_raw);
|
||||
|
||||
// Ix2states[0] = Ix2;
|
||||
// Ix2weight[0] = ;
|
||||
int n_states_proper = 0;
|
||||
for(int i=0; i < n_states_raw; ++i) {
|
||||
//only symmetric modifications
|
||||
for(int mod_index = 0; mod_index<n_uncertain; ++mod_index) {
|
||||
if((i & (1 << mod_index)) >> mod_index != 0) {
|
||||
Ix2states[n_states_proper][index_uncertain[mod_index]] += (-2)*Ix2_uncertain[mod_index];
|
||||
////Ix2states[state_index][N - 1 - hole_position[mod_index]] += (2)*holes[hole_position[mod_index]];
|
||||
}
|
||||
}
|
||||
//check if it's a proper set of quantum numbers
|
||||
bool OK = true;
|
||||
for(int j=0; j<N-1; ++j) if(Ix2states[n_states_proper][j] == Ix2states[n_states_proper][j+1]) OK = false;
|
||||
|
||||
if(OK) {
|
||||
DP sum = 0;
|
||||
for(int j=0; j<N; ++j) sum += abs(Ix2_found[j] - Ix2states[n_states_proper][j]);
|
||||
Ix2weight[n_states_proper] = exp(-sum);
|
||||
n_states_proper++;
|
||||
}
|
||||
else Ix2states[n_states_proper] = Ix2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//sort the states in increasing weight order;
|
||||
Vect<int> index(0, n_states_raw);
|
||||
for (int nrs = 0; nrs < n_states_raw; ++nrs) index[nrs] = nrs;
|
||||
Ix2weight.QuickSort(index);
|
||||
|
||||
//cut the number of states if above 21 <- arbitrary number for now
|
||||
nstates = min(n_states_proper, 21);
|
||||
cout << n_states_raw << "\t" << n_states_proper << "\t" << nstates << endl;
|
||||
|
||||
//create ensamble of states with normalised weights and ordered accordingly
|
||||
LiebLin_Bethe_State rhostate(c_int, N, L);
|
||||
rhostate.Ix2 = Ix2;
|
||||
rhostate.Compute_All(true);
|
||||
|
||||
state = Vect<LiebLin_Bethe_State>(rhostate, nstates);
|
||||
weight = Vect<DP>(nstates);
|
||||
|
||||
DP sum_weight = 0.0;
|
||||
for(int i=0; i<nstates; ++i) {
|
||||
state[i].Ix2 = Ix2states[index[n_states_raw - i - 1]];
|
||||
state[i].Set_Label_from_Ix2 (state[0].Ix2);
|
||||
weight[i] = Ix2weight[n_states_raw - i - 1];
|
||||
sum_weight += weight[i];
|
||||
}
|
||||
|
||||
//renormalise
|
||||
for(int i=0; i<nstates; ++i) weight[i] /= sum_weight;
|
||||
|
||||
// for(int i=0; i<nstates; ++i) {
|
||||
// cout << weight[i] << "\t" << state[i].Ix2 << endl;
|
||||
// }
|
||||
|
||||
return;
|
||||
*/
|
||||
//cout << rho_t.value << endl;
|
||||
|
||||
// different attempts - to delete soon
|
||||
// JSCerror("Stop here.");
|
||||
/*
|
||||
|
||||
// This function returns a state ensemble matching the continuous density rho.
|
||||
// The logic closely resembles the one used in Discretized_LiebLin_Bethe_State.
|
||||
|
||||
// Now carry on as per Discretized_LiebLin_Bethe_State:
|
||||
// Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
|
||||
DP integral = 0.0;
|
||||
DP integral_prev = 0.0;
|
||||
int Nfound = 0;
|
||||
Vect<DP> lambda_found(0.0, 2*N);
|
||||
|
||||
for (int i = 0; i < rho.Npts; ++i) {
|
||||
integral_prev = integral;
|
||||
integral += L * rho.value[i] * rho.dlambda[i];
|
||||
//cout << x.value[i] << "\t" << integral << endl;
|
||||
if (integral > Nfound + 0.5) {
|
||||
cout << L*x.value[i] << "\t" << integral << endl;
|
||||
// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
|
||||
if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
|
||||
lambda_found[Nfound++] = 0.25 * (3.0 * rho.lambda[i-1] + rho.lambda[i]);
|
||||
lambda_found[Nfound++] = 0.25 * (rho.lambda[i-1] + 3.0 * rho.lambda[i]);
|
||||
}
|
||||
else {
|
||||
//lambda_found[Nfound] = rho.lambda[i];
|
||||
// Better: center the lambda_found between these points:
|
||||
//lambda_found[Nfound] = rho.lambda[i-1] + (rho.lambda[i] - rho.lambda[i-1]) * ((Nfound + 1.0) - integral_prev)/(integral - integral_prev);
|
||||
lambda_found[Nfound] = 0.5 * (rho.lambda[i-1] + rho.lambda[i]);
|
||||
Nfound++;
|
||||
}
|
||||
}
|
||||
//cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
|
||||
}
|
||||
//cout << "rho: " << rho.Npts << " points" << endl << rho.value << endl;
|
||||
//cout << "sym: " << rho.value[0] << " " << rho.value[rho.value.size() - 1]
|
||||
// << "\t" << rho.value[rho.value.size()/2] << " " << rho.value[rho.value.size()/2 + 1] << endl;
|
||||
//cout << "Found " << Nfound << " particles." << endl;
|
||||
//cout << "lambda_found = " << lambda_found << endl;
|
||||
|
||||
Vect<DP> lambda(N);
|
||||
// Fill up the found rapidities:
|
||||
for (int il = 0; il < JSC::min(N, Nfound); ++il) lambda[il] = lambda_found[il];
|
||||
// If there are missing ones, put them at the end; ideally, this should never be called
|
||||
for (int il = Nfound; il < N; ++il) lambda[il] = lambda_found[Nfound-1] + (il - Nfound + 1) * (lambda_found[Nfound-1] - lambda_found[Nfound-2]);
|
||||
|
||||
//cout << lambda << endl;
|
||||
*/
|
||||
//try a different method
|
||||
//first determine bins, that is intervals in lambda which contain a single rapidity
|
||||
/*
|
||||
Vect<int> lambda_bin(0.0, N+1);
|
||||
integral = 0.0;
|
||||
Nfound = 0;
|
||||
|
||||
lambda_bin[0] = 0;
|
||||
lambda_bin[N] = rho.Npts-1;
|
||||
for(int i=0; i<rho.Npts; ++i) {
|
||||
integral += L * rho.value[i] * rho.dlambda[i];
|
||||
if (integral > Nfound + 1.0) lambda_bin[++Nfound] = i - (rho.lambda[i]>0);
|
||||
}
|
||||
|
||||
//put rapidity at the mean value of the distribution inside the bin
|
||||
for(int ib=0; ib < N; ++ib) {
|
||||
lambda_found[ib] = 0.0;
|
||||
for(int i=lambda_bin[ib]; i<lambda_bin[ib+1]; ++i) lambda_found[ib] += L * rho.value[i] * rho.lambda[i] * rho.dlambda[i];
|
||||
}
|
||||
|
||||
//cout << lambda_found << endl;
|
||||
|
||||
for(int i=0; i<N; ++i) cout << L*lambda[i]/PI << "\t" << L*lambda_found[i]/PI << endl;
|
||||
|
||||
|
||||
JSCerror("Stop here.");
|
||||
*/
|
||||
/*
|
||||
// Calculate quantum numbers: 2\pi * (L lambda + \sum_j 2 atan((lambda - lambda_j)/c)) = I_j
|
||||
// Use rounding.
|
||||
Vect<DP> Ix2_exact(N);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
DP sum = 0.0;
|
||||
for (int j = 0; j < N; ++j) sum += 2.0 * atan((lambda[i] - lambda[j])/c_int);
|
||||
Ix2_exact[i] = (L * lambda[i] + sum)/PI;
|
||||
Ix2_left[i] = floor(Ix2_exact[i]);
|
||||
Ix2_left[i] -= (Ix2_left[i] + N + 1)%2 ? 1 : 0;
|
||||
Ix2_right[i] = ceil(Ix2_exact[i]);
|
||||
Ix2_right[i] += (Ix2_right[i] + N + 1)%2 ? 1 : 0;
|
||||
|
||||
//cout << Ix2_left[i] << "\t" << Ix2_exact[i] << "\t" << Ix2_right[i] << endl;
|
||||
//Ix2[i] = 2.0* int((L * lambda[i] + sum)/twoPI) + (N % 2) - 1;
|
||||
// For N is even/odd, we want to round off to the nearest odd/even integer.
|
||||
//Ix2[i] = 2.0 * floor((L* lambda[i] + sum)/twoPI + 0.5 * (N%2 ? 1 : 2)) + (N%2) - 1;
|
||||
}
|
||||
//cout << "Found quantum numbers " << endl << Ix2 << endl;
|
||||
*/
|
||||
|
||||
/*
|
||||
//create the reference state and mark possible hole positions
|
||||
Vect<int> Ix2(N);
|
||||
Vect<float> holes(0.0, N);
|
||||
for(int i=0; i < N; ++i) {
|
||||
if(Ix2_found[i] - Ix2_left[i] < 1) {
|
||||
Ix2[i] = Ix2_left[i];
|
||||
if(Ix2_found[i] - Ix2_left[i] > 0.75) holes[i] = -1;
|
||||
}
|
||||
else {
|
||||
Ix2[i] = Ix2_right[i];
|
||||
if(Ix2_right[i] - Ix2_found[i] > 0.75) holes[i] = 1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
// cout << endl << Ix2 << endl;
|
||||
// cout << endl << holes << endl;
|
||||
/*
|
||||
//count number of possible states
|
||||
int n = 0;
|
||||
for(int i=0; i < N; ++i) {
|
||||
if(holes[i] != 0) ++n;
|
||||
}
|
||||
int n_states_raw = 1;
|
||||
*/
|
||||
/* only symmetric modifications
|
||||
for(int i=0; i<0.5*n; ++i) n_states_raw *= 2.0; //we count only symmetric modiications
|
||||
|
||||
Vect<Vect<int> > Ix2states(Ix2, n_states_raw);
|
||||
|
||||
Vect<int> hole_position(0, 0.5*n);
|
||||
int hole_index = 0;
|
||||
for(int i=N/2 + N%2; i<N; ++i) {
|
||||
if(holes[i] != 0) hole_position[hole_index++] = i;
|
||||
}
|
||||
|
||||
|
||||
//create modifications, we use bit representation of integers between 0 and n_states-1 treating zero as no change and 1 as mutltiplication by -1
|
||||
int state_index = 1;
|
||||
for(int i=1; i < n_states_raw; ++i) {
|
||||
//only symmetric modifications
|
||||
for(int mod_index = 0; mod_index<0.5*n; ++mod_index) {
|
||||
if((i & (1 << mod_index)) >> mod_index != 0) {
|
||||
Ix2states[state_index][hole_position[mod_index]] += (-2)*holes[hole_position[mod_index]];
|
||||
Ix2states[state_index][N - 1 - hole_position[mod_index]] += (2)*holes[hole_position[mod_index]];
|
||||
}
|
||||
}
|
||||
//check if it's a proper set of quantum numbers
|
||||
bool OK = true;
|
||||
for(int j=0; j<N-1; ++j) if(Ix2states[state_index][j] == Ix2states[state_index][j+1]) OK = false;
|
||||
|
||||
if(OK) state_index++;
|
||||
else Ix2states[state_index] = Ix2;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
for(int i=0; i<n; ++i) n_states_raw *= 2.0; //we count all posibilities
|
||||
|
||||
Vect<Vect<int> > Ix2states(Ix2, n_states_raw);
|
||||
|
||||
Vect<int> hole_position(0, n);
|
||||
int hole_index = 0;
|
||||
for(int i=0; i<N; ++i) {
|
||||
if(holes[i] != 0) hole_position[hole_index++] = i;
|
||||
}
|
||||
|
||||
|
||||
//create modifications, we use bit representation of integers between 0 and n_states-1 treating zero as no change and 1 as mutltiplication by -1
|
||||
int state_index = 1;
|
||||
for(int i=1; i < n_states_raw; ++i) {
|
||||
//only symmetric modifications
|
||||
for(int mod_index = 0; mod_index<n; ++mod_index) {
|
||||
if((i & (1 << mod_index)) >> mod_index != 0) {
|
||||
Ix2states[state_index][hole_position[mod_index]] += (-2)*holes[hole_position[mod_index]];
|
||||
//Ix2states[state_index][N - 1 - hole_position[mod_index]] += (2)*holes[hole_position[mod_index]];
|
||||
}
|
||||
}
|
||||
//check if it's a proper set of quantum numbers
|
||||
bool OK = true;
|
||||
for(int j=0; j<N-1; ++j) if(Ix2states[state_index][j] == Ix2states[state_index][j+1]) OK = false;
|
||||
|
||||
if(OK) state_index++;
|
||||
else Ix2states[state_index] = Ix2;
|
||||
}
|
||||
|
||||
*/
|
||||
/*
|
||||
n_states_raw = state_index;
|
||||
// for(int i=0; i<n_states; ++i) cout << Ix2states[i] << endl;
|
||||
|
||||
LiebLin_Bethe_State rhostate(c_int, N, L);
|
||||
rhostate.Ix2 = Ix2;
|
||||
rhostate.Compute_All(true);
|
||||
|
||||
Vect<LiebLin_Bethe_State> state_raw = Vect<LiebLin_Bethe_State>(rhostate, n_states_raw);
|
||||
Vect<DP> weight_raw(0.0, n_states_raw);
|
||||
*/
|
||||
|
||||
/*
|
||||
DP energy_rho = 0;
|
||||
for (int i = 0; i < rho.Npts; ++i) {
|
||||
energy_rho += L * rho.value[i] * rho.dlambda[i] * rho.lambda[i] * rho.lambda[i];
|
||||
}
|
||||
|
||||
cout << energy_rho << endl;
|
||||
|
||||
DP energy_discrete = 0;
|
||||
for (int i=0; i < N; ++i) {
|
||||
energy_discrete += lambda[i] * lambda[i];
|
||||
}
|
||||
energy_discrete /= N;
|
||||
cout << energy_discrete;
|
||||
*/
|
||||
/*
|
||||
DP sum_weight_raw = 0.0;
|
||||
for(int i=0; i<n_states_raw; ++i) {
|
||||
//state_raw[i].Ix2 = Ix2states[i];
|
||||
//state_raw[i].Set_Label_from_Ix2 (state_raw[0].Ix2);
|
||||
//state_raw[i].Compute_All(true);
|
||||
DP sum = 0;
|
||||
for(int j=0; j<N; ++j) sum += fabs(Ix2states[i][j] - Ix2_found[j]);
|
||||
weight_raw[i] = exp(sum)/L;
|
||||
|
||||
sum_weight_raw += weight_raw[i];
|
||||
}
|
||||
|
||||
for(int i=0; i<n_states_raw; ++i) weight_raw[i] /= sum_weight_raw;
|
||||
|
||||
// Order the weights in decreasing value:
|
||||
Vect<int> index(n_states_raw);
|
||||
for (int nrs = 0; nrs < n_states_raw; ++nrs) index[nrs] = nrs;
|
||||
weight_raw.QuickSort(index);
|
||||
|
||||
//nstates = 0;
|
||||
//for(int i=0; i<n_states_raw; ++i) if (weight_raw[i] > 0.01) ++nstates;
|
||||
|
||||
nstates = JSC::min(n_states_raw, 21);
|
||||
|
||||
cout << nstates << endl;
|
||||
|
||||
state = Vect<LiebLin_Bethe_State>(rhostate, nstates);
|
||||
weight = Vect<DP>(nstates);
|
||||
|
||||
DP sum_weight = 0.0;
|
||||
for(int i=0; i<nstates; ++i) {
|
||||
state[i].Ix2 = Ix2states[index[i]];
|
||||
state[i].Set_Label_from_Ix2 (state[0].Ix2);
|
||||
weight[i] = weight_raw[index[i]];
|
||||
sum_weight += weight[i];
|
||||
}
|
||||
|
||||
//renormalise
|
||||
for(int i=0; i<nstates; ++i) weight[i] /= sum_weight;
|
||||
|
||||
for(int i=0; i<nstates; ++i) {
|
||||
cout << weight[i] << "\t" << state[i].Ix2 << endl;
|
||||
}
|
||||
*/
|
||||
//JSCerror("Stop here.");
|
||||
|
||||
// end of different attempts
|
||||
/*
|
||||
// Check that the quantum numbers are all distinct:
|
||||
bool allOK = false;
|
||||
while (!allOK) {
|
||||
for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1] && Ix2[i] < 0) Ix2[i] -= 2;
|
||||
for (int i = 1; i < N; ++i) if (Ix2[i] == Ix2[i-1] && Ix2[i] > 0) Ix2[i] += 2;
|
||||
allOK = true;
|
||||
for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1]) allOK = false;
|
||||
}
|
||||
//cout << "Found modified quantum numbers " << endl << Ix2 << endl;
|
||||
|
||||
LiebLin_Bethe_State rhostate(c_int, N, L);
|
||||
rhostate.Ix2 = Ix2;
|
||||
rhostate.Compute_All(true);
|
||||
//cout << "rapidities of state found: " << rhostate.lambda << endl;
|
||||
|
||||
// Until here, the code is identical to that in Discretized_LiebLin_Bethe_State.
|
||||
// Construct states in the vicinity by going through type 2 descendents recursively:
|
||||
int ndesc_type2 = 0;
|
||||
int* ndesc_type2_ptr = &ndesc_type2;
|
||||
Generate_type_2_descendents (rhostate, ndesc_type2_ptr, rhostate);
|
||||
|
||||
|
||||
cout << "Found " << ndesc_type2 << " descendents for state " << rhostate << endl;
|
||||
//JSCerror("Stop here...");
|
||||
|
||||
// Now try to construct states in the vicinity.
|
||||
int nrstates1mod = 1;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (i == 0 || Ix2[i-1] < Ix2[i] - 2) nrstates1mod++;
|
||||
if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) nrstates1mod++;
|
||||
}
|
||||
//if (nrstates1mod < nstates_req) JSCerror("nrstates1mod < nstates_req in LiebLin_Diagonal_State_Ensemble.");
|
||||
nstates = nrstates1mod;
|
||||
|
||||
Vect<Vect<int> > Ix2states1mod(nrstates1mod);
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) Ix2states1mod[nrs] = Vect<int> (N);
|
||||
|
||||
int nfound = 0;
|
||||
Ix2states1mod[nfound++] = Ix2; // this is the sp state
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (i == 0 || Ix2[i-1] < Ix2[i] - 2) {
|
||||
Ix2states1mod[nfound] = Ix2;
|
||||
Ix2states1mod[nfound++][i] -= 2;
|
||||
}
|
||||
if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) {
|
||||
Ix2states1mod[nfound] = Ix2;
|
||||
Ix2states1mod[nfound++][i] += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate the weight of all found states:
|
||||
Vect<DP> rawweight(nrstates1mod);
|
||||
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) {
|
||||
DP sumweight = 0.0;
|
||||
for (int i = 0; i < N; ++i) sumweight += fabs(Ix2states1mod[nrs][i] - Ix2_exact[i]);
|
||||
rawweight[nrs] = exp(-sumweight/log(L));
|
||||
}
|
||||
|
||||
// Order the weights in decreasing value:
|
||||
Vect<int> index(nrstates1mod);
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) index[nrs] = nrs;
|
||||
rawweight.QuickSort(index);
|
||||
|
||||
// Calculate weight normalization:
|
||||
DP weightnorm = 0.0;
|
||||
//for (int ns = 0; ns < nstates_req; ++ns) weightnorm += rawweight[nrstates1mod - 1 - ns];
|
||||
for (int ns = 0; ns < nstates; ++ns) weightnorm += rawweight[nrstates1mod - 1 - ns];
|
||||
|
||||
state = Vect<LiebLin_Bethe_State>(rhostate, nstates);
|
||||
weight = Vect<DP> (nstates);
|
||||
|
||||
for (int ns = 0; ns < nstates; ++ns) {
|
||||
weight[ns] = rawweight[nrstates1mod - 1 - ns]/weightnorm;
|
||||
state[ns].Ix2 = Ix2states1mod[index[nrstates1mod - 1 - ns] ];
|
||||
state[ns].Set_Label_from_Ix2 (rhostate.Ix2);
|
||||
state[ns].Compute_All(true);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho, int nstates_req)
|
||||
: nstates(nstates_req)
|
||||
{
|
||||
// This function returns a state ensemble matching the continuous density rho.
|
||||
// The logic closely resembles the one used in Discretized_LiebLin_Bethe_State.
|
||||
|
||||
// Each `exact' (from rho) quantum number is matched to its two possible values,
|
||||
// assigning a probability to each according to the proximity of the quantum number values.
|
||||
|
||||
// The set is then ordered in energy, and split into nstates_req boxes from which one
|
||||
// representative is selected, and given the probability = sum of probabilities in the box.
|
||||
|
||||
|
||||
// Begin as per Discretized_LiebLin_Bethe_State, to find the saddle-point state.
|
||||
// Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
|
||||
DP integral = 0.0;
|
||||
DP integral_prev = 0.0;
|
||||
int Nfound = 0;
|
||||
Vect<DP> lambda_found(0.0, 2*N);
|
||||
|
||||
for (int i = 0; i < rho.Npts; ++i) {
|
||||
integral_prev = integral;
|
||||
integral += L * rho.value[i] * rho.dlambda[i];
|
||||
if (integral > Nfound + 0.5) {
|
||||
// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
|
||||
if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
|
||||
lambda_found[Nfound++] = 0.25 * (3.0 * rho.lambda[i-1] + rho.lambda[i]);
|
||||
lambda_found[Nfound++] = 0.25 * (rho.lambda[i-1] + 3.0 * rho.lambda[i]);
|
||||
}
|
||||
else {
|
||||
//lambda_found[Nfound] = rho.lambda[i];
|
||||
// Better: center the lambda_found between these points:
|
||||
//lambda_found[Nfound] = rho.lambda[i-1] + (rho.lambda[i] - rho.lambda[i-1]) * ((Nfound + 1.0) - integral_prev)/(integral - integral_prev);
|
||||
lambda_found[Nfound] = 0.5 * (rho.lambda[i-1] + rho.lambda[i]);
|
||||
Nfound++;
|
||||
}
|
||||
}
|
||||
//cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
|
||||
}
|
||||
//cout << "rho: " << rho.Npts << " points" << endl << rho.value << endl;
|
||||
//cout << "sym: " << rho.value[0] << " " << rho.value[rho.value.size() - 1]
|
||||
// << "\t" << rho.value[rho.value.size()/2] << " " << rho.value[rho.value.size()/2 + 1] << endl;
|
||||
//cout << "Found " << Nfound << " particles." << endl;
|
||||
//cout << "lambda_found = " << lambda_found << endl;
|
||||
|
||||
Vect<DP> lambda(N);
|
||||
// Fill up the found rapidities:
|
||||
for (int il = 0; il < JSC::min(N, Nfound); ++il) lambda[il] = lambda_found[il];
|
||||
// If there are missing ones, put them at the end; ideally, this should never be called
|
||||
for (int il = Nfound; il < N; ++il) lambda[il] = lambda_found[Nfound-1] + (il - Nfound + 1) * (lambda_found[Nfound-1] - lambda_found[Nfound-2]);
|
||||
|
||||
// Calculate quantum numbers: 2\pi * (L lambda + \sum_j 2 atan((lambda - lambda_j)/c)) = I_j
|
||||
// Use rounding.
|
||||
Vect<DP> Ix2_exact(N);
|
||||
Vect<int> Ix2(N);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
DP sum = 0.0;
|
||||
for (int j = 0; j < N; ++j) sum += 2.0 * atan((lambda[i] - lambda[j])/c_int);
|
||||
Ix2_exact[i] = (L * lambda[i] + sum)/PI;
|
||||
//Ix2[i] = 2.0* int((L * lambda[i] + sum)/twoPI) + (N % 2) - 1;
|
||||
// For N is even/odd, we want to round off to the nearest odd/even integer.
|
||||
Ix2[i] = 2.0 * floor((L* lambda[i] + sum)/twoPI + 0.5 * (N%2 ? 1 : 2)) + (N%2) - 1;
|
||||
}
|
||||
//cout << "Found quantum numbers " << endl << Ix2 << endl;
|
||||
|
||||
// Check that the quantum numbers are all distinct:
|
||||
bool allOK = false;
|
||||
while (!allOK) {
|
||||
for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1] && Ix2[i] < 0) Ix2[i] -= 2;
|
||||
for (int i = 1; i < N; ++i) if (Ix2[i] == Ix2[i-1] && Ix2[i] > 0) Ix2[i] += 2;
|
||||
allOK = true;
|
||||
for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1]) allOK = false;
|
||||
}
|
||||
//cout << "Found modified quantum numbers " << endl << Ix2 << endl;
|
||||
|
||||
LiebLin_Bethe_State rhostate(c_int, N, L);
|
||||
rhostate.Ix2 = Ix2;
|
||||
rhostate.Compute_All(true);
|
||||
//cout << "rapidities of state found: " << rhostate.lambda << endl;
|
||||
|
||||
// Until here, the code is identical to that in Discretized_LiebLin_Bethe_State.
|
||||
|
||||
// Now try to construct states in the vicinity.
|
||||
int nrstates1mod = 1;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (i == 0 || Ix2[i-1] < Ix2[i] - 2) nrstates1mod++;
|
||||
if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) nrstates1mod++;
|
||||
}
|
||||
if (nrstates1mod < nstates_req) JSCerror("nrstates1mod < nstates_req in LiebLin_Diagonal_State_Ensemble.");
|
||||
|
||||
Vect<Vect<int> > Ix2states1mod(nrstates1mod);
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) Ix2states1mod[nrs] = Vect<int> (N);
|
||||
|
||||
int nfound = 0;
|
||||
Ix2states1mod[nfound++] = Ix2; // this is the sp state
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (i == 0 || Ix2[i-1] < Ix2[i] - 2) {
|
||||
Ix2states1mod[nfound] = Ix2;
|
||||
Ix2states1mod[nfound++][i] -= 2;
|
||||
}
|
||||
if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) {
|
||||
Ix2states1mod[nfound] = Ix2;
|
||||
Ix2states1mod[nfound++][i] += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate the weight of all found states:
|
||||
Vect<DP> rawweight(nrstates1mod);
|
||||
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) {
|
||||
DP sumweight = 0.0;
|
||||
for (int i = 0; i < N; ++i) sumweight += fabs(Ix2states1mod[nrs][i] - Ix2_exact[i]);
|
||||
rawweight[nrs] = exp(-sumweight/log(L));
|
||||
}
|
||||
|
||||
// Order the weights in decreasing value:
|
||||
Vect<int> index(nrstates1mod);
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) index[nrs] = nrs;
|
||||
rawweight.QuickSort(index);
|
||||
|
||||
// Calculate weight normalization:
|
||||
DP weightnorm = 0.0;
|
||||
for (int ns = 0; ns < nstates_req; ++ns) weightnorm += rawweight[nrstates1mod - 1 - ns];
|
||||
|
||||
state = Vect<LiebLin_Bethe_State>(rhostate, nstates_req);
|
||||
weight = Vect<DP> (nstates_req);
|
||||
|
||||
for (int ns = 0; ns < nstates_req; ++ns) {
|
||||
weight[ns] = rawweight[nrstates1mod - 1 - ns]/weightnorm;
|
||||
state[ns].Ix2 = Ix2states1mod[index[nrstates1mod - 1 - ns] ];
|
||||
state[ns].Set_Label_from_Ix2 (rhostate.Ix2);
|
||||
state[ns].Compute_All(true);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
LiebLin_Diagonal_State_Ensemble& LiebLin_Diagonal_State_Ensemble::operator= (const LiebLin_Diagonal_State_Ensemble& rhs)
|
||||
{
|
||||
if (this != &rhs) {
|
||||
nstates = rhs.nstates;
|
||||
state = rhs.state;
|
||||
weight = rhs.weight;
|
||||
}
|
||||
|
||||
return(*this);
|
||||
}
|
||||
|
||||
void LiebLin_Diagonal_State_Ensemble::Load (DP c_int, DP L, int N, const char* ensfile_Cstr)
|
||||
{
|
||||
ifstream infile(ensfile_Cstr);
|
||||
|
||||
// Count nr of lines in file:
|
||||
string dummy;
|
||||
int nrlines = 0;
|
||||
while (getline(infile, dummy)) ++nrlines;
|
||||
infile.close();
|
||||
|
||||
//cout << "Found " << nrlines << " lines in ens file." << endl;
|
||||
nstates = nrlines;
|
||||
LiebLin_Bethe_State examplestate (c_int, L, N);
|
||||
state = Vect<LiebLin_Bethe_State> (examplestate, nstates);
|
||||
weight = Vect<DP> (0.0, nstates);
|
||||
|
||||
infile.open(ensfile_Cstr);
|
||||
|
||||
string dummylabel;
|
||||
for (int ns = 0; ns < nstates; ++ns) {
|
||||
infile >> weight[ns] >> dummylabel;
|
||||
for (int i = 0; i < state[ns].N; ++i) infile >> state[ns].Ix2[i];
|
||||
}
|
||||
infile.close();
|
||||
|
||||
for (int ns = 0; ns < nstates; ++ns) {
|
||||
state[ns].Set_Label_from_Ix2 (state[0].Ix2); // labels are ref to the saddle-point state
|
||||
state[ns].Compute_All(true);
|
||||
}
|
||||
}
|
||||
|
||||
void LiebLin_Diagonal_State_Ensemble::Save (const char* ensfile_Cstr)
|
||||
{
|
||||
ofstream outfile;
|
||||
|
||||
outfile.open(ensfile_Cstr);
|
||||
|
||||
for (int ns = 0; ns < nstates; ++ns) {
|
||||
if (ns > 0) outfile << endl;
|
||||
outfile << setprecision(16) << weight[ns] << "\t" << state[ns].label << "\t";
|
||||
for (int i = 0; i < state[ns].N; ++i) outfile << " " << state[ns].Ix2[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT, int nstates_req)
|
||||
LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT)
|
||||
{
|
||||
// This function constructs a manifold of states around the thermal saddle-point.
|
||||
|
||||
// Start as per Canonical_Saddle_Point_State:
|
||||
|
||||
// This function returns the discretized state minimizing the canonical free energy
|
||||
// F = E - T S.
|
||||
|
||||
// This is obtained by rediscretizing the solution coming from TBA.
|
||||
|
||||
|
||||
// Otherwise, return the discretized TBA saddle-point state:
|
||||
LiebLin_TBA_Solution TBAsol = LiebLin_TBA_Solution_fixed_nbar (c_int, N/L, kBT, 1.0e-4, 100);
|
||||
|
||||
LiebLin_Diagonal_State_Ensemble ensemble(c_int, L, N, TBAsol.rho);
|
||||
|
||||
cout << "nbar: " << TBAsol.nbar << endl;
|
||||
cout << "ebar: " << TBAsol.ebar << endl;
|
||||
|
||||
cout << ensemble.state[0].E << endl;
|
||||
//return(LiebLin_Diagonal_State_Ensemble (c_int, L, N, TBAsol.rho, nstates_req));
|
||||
return(ensemble);
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,302 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/LIEBLIN/LiebLin_Sumrules.cc
|
||||
|
||||
Purpose: provides functions evaluating various sumrule factors
|
||||
for Lieb-Liniger.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
//DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, bool fixed_iK, int iKneeded)
|
||||
DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
|
||||
{
|
||||
DP sumrule_factor = 1.0;
|
||||
|
||||
//if (!fixed_iK) {
|
||||
if (iKmin != iKmax) {
|
||||
if (whichDSF == 'Z') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'd' || whichDSF == '1') {
|
||||
|
||||
// Here, we use a measure decreasing in K with K^2.
|
||||
// We sum up omega * MEsq/(iK^2) for all values of iKmin <= iK <= iKmax, discounting iK == 0 (where DSF vanishes)
|
||||
// We therefore have (N/L) x L^{-1} x (2\pi/L)^2 x (iKmax - iKmin + 1) = 4 \pi^2 x N x (iKmax - iKmin + 1)/L^4
|
||||
// Discounting iK == 0 (where DSF vanishes), if iKmin <= 0 && iKmax >= 0 (in which case 0 is containted in [iKmin, iKmax])
|
||||
sumrule_factor = (iKmin <= 0 && iKmax >= 0) ?
|
||||
(RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin))
|
||||
: (RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin + 1));
|
||||
|
||||
/*
|
||||
// Measure using the g2(0) + delta function: // DOES NOT WORK VERY WELL
|
||||
DP dE0_dc = LiebLin_dE0_dc (RefState.c_int, RefState.L, RefState.N);
|
||||
//sumrule_factor = 1.0/((dE0_dc + (2.0 * RefState.Tableau[0].Ncols + 1.0)*RefState.N/RefState.L)/RefState.L);
|
||||
// Assume that iKmin == 0 here:
|
||||
//sumrule_factor = 1.0/((dE0_dc + (2*iKmax + 1)*RefState.N/RefState.L)/RefState.L);
|
||||
// For iKmin != 0:
|
||||
sumrule_factor = 1.0/((dE0_dc + (iKmax - iKmin + 1)*RefState.N/RefState.L)/RefState.L);
|
||||
*/
|
||||
}
|
||||
// For the Green's function, it's the delta function \delta(x = 0) plus the density:
|
||||
//else if (whichDSF == 'g') sumrule_factor = 1.0/((2.0 * RefState.Tableau[0].Ncols + 1.0)/RefState.L + RefState.N/RefState.L);
|
||||
// Assume that iKmin == 0 here:
|
||||
//else if (whichDSF == 'g') sumrule_factor = 1.0/(2.0* iKmax + 1.0)/RefState.L + RefState.N/RefState.L);
|
||||
else if (whichDSF == 'g')
|
||||
sumrule_factor = 1.0/((abs(iKmax - iKmin) + 1.0)/RefState.L + RefState.N/RefState.L);
|
||||
//sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
|
||||
// For the one-body function, it's just the density:
|
||||
else if (whichDSF == 'o') sumrule_factor = RefState.L/RefState.N;
|
||||
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'B') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'C') sumrule_factor = 1.0;
|
||||
else JSCerror("whichDSF option not consistent in Sumrule_Factor");
|
||||
}
|
||||
|
||||
//else if (fixed_iK) {
|
||||
else if (iKmin == iKmax) {
|
||||
if (whichDSF == 'Z') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'd' || whichDSF == '1')
|
||||
//// We sum up omega * MEsq/(iK^2): this should give (1/L) x (N/L) x k^2 = N x (2\pi)^2/L^4
|
||||
//sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * RefState.N);
|
||||
// We sum up omega * MEsq
|
||||
//sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * iKneeded * iKneeded * RefState.N);
|
||||
sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * iKmax * iKmax * RefState.N);
|
||||
else if (whichDSF == 'g' || whichDSF == 'o') {
|
||||
// We sum up omega * MEsq
|
||||
//sumrule_factor = 1.0/((pow(twoPI * iKneeded/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
|
||||
sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
|
||||
}
|
||||
//else if (whichDSF == 'o') sumrule_factor = RefState.L/RefState.N;
|
||||
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'B') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'C') sumrule_factor = 1.0;
|
||||
else JSCerror("whichDSF option not consistent in Sumrule_Factor");
|
||||
}
|
||||
|
||||
return(sumrule_factor);
|
||||
}
|
||||
|
||||
void Evaluate_F_Sumrule (char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax, const char* RAW_Cstr, const char* FSR_Cstr)
|
||||
{
|
||||
|
||||
ifstream infile;
|
||||
infile.open(RAW_Cstr);
|
||||
if(infile.fail()) {
|
||||
cout << "Filename RAW_Cstr = " << RAW_Cstr << endl;
|
||||
JSCerror("Could not open input file in Evaluate_F_Sumrule(LiebLin...).");
|
||||
}
|
||||
|
||||
// We run through the data file to check the f sumrule at each positive momenta:
|
||||
//int iK_UL = RefState.Tableau[0].Ncols; // this is iK_UL
|
||||
//Vect<DP> Sum_omega_MEsq(0.0, iK_UL + 1);
|
||||
Vect_DP Sum_omega_MEsq (0.0, iKmax - iKmin + 1);
|
||||
Vect_DP Sum_abs_omega_MEsq (0.0, iKmax - iKmin + 1);
|
||||
|
||||
DP Sum_MEsq = 0.0;
|
||||
|
||||
DP omega, ME;
|
||||
int iK;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
int nr, nl;
|
||||
|
||||
int nraw = 0;
|
||||
|
||||
while (infile.peek() != EOF) {
|
||||
nraw++;
|
||||
infile >> omega >> iK >> ME >> dev >> label;
|
||||
if (whichDSF == '1') infile >> nr >> nl;
|
||||
//if (iK > 0 && iK <= iK_UL) Sum_omega_MEsq[iK] += omega * MEsq;
|
||||
if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
|
||||
if (iK >= iKmin && iK <= iKmax) Sum_abs_omega_MEsq[iK - iKmin] += fabs(omega * ME * ME);
|
||||
Sum_MEsq += ME * ME;
|
||||
}
|
||||
|
||||
infile.close();
|
||||
|
||||
//cout << "Read " << nraw << " entries in raw file." << endl;
|
||||
|
||||
ofstream outfile;
|
||||
outfile.open(FSR_Cstr);
|
||||
outfile.precision(16);
|
||||
|
||||
if (whichDSF == 'd' || whichDSF == '1') {
|
||||
/*
|
||||
outfile << 0 << "\t" << 1; // full saturation at k = 0 !
|
||||
for (int i = 1; i <= iK_UL; ++i)
|
||||
outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L * RefState.L
|
||||
* RefState.L * RefState.L/(4.0 * PI * PI * i * i * RefState.N);
|
||||
*/
|
||||
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
|
||||
if (i > iKmin) outfile << endl;
|
||||
//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * JSC::max(abs(i), 1), 2.0) * RefState.N);
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * JSC::max(abs(i), 1), 2.0) * RefState.N)
|
||||
// Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
|
||||
// so -iK is at index index(-iK) = -iK - iKmin
|
||||
// We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
|
||||
<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
|
||||
0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin])
|
||||
: Sum_omega_MEsq[i - iKmin])
|
||||
* pow(RefState.L, 4.0)/(pow(2.0 * PI * JSC::max(abs(i), 1), 2.0) * RefState.N);
|
||||
}
|
||||
}
|
||||
else if (whichDSF == 'g' || whichDSF == 'o') {
|
||||
/*
|
||||
for (int i = 0; i <= iK_UL; ++i)
|
||||
outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L
|
||||
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
//cout << "Sum_MEsq = " << Sum_MEsq << "\tN/L = " << RefState.N/RefState.L << endl;
|
||||
*/
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
if (i > iKmin) outfile << endl;
|
||||
//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
|
||||
///((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
|
||||
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
|
||||
<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
|
||||
0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin]) : Sum_omega_MEsq[i - iKmin])
|
||||
* RefState.L/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
}
|
||||
}
|
||||
|
||||
outfile.close();
|
||||
|
||||
}
|
||||
|
||||
void Evaluate_F_Sumrule (string prefix, char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
|
||||
{
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
FSR_stringstream << prefix << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
|
||||
Evaluate_F_Sumrule (whichDSF, RefState, Chem_Pot, iKmin, iKmax, RAW_Cstr, FSR_Cstr);
|
||||
|
||||
}
|
||||
|
||||
// Using diagonal state ensemble:
|
||||
void Evaluate_F_Sumrule (char whichDSF, DP c_int, DP L, int N, DP kBT, int nstates_req, DP Chem_Pot, int iKmin, int iKmax, const char* FSR_Cstr)
|
||||
{
|
||||
|
||||
// We run through the data file to check the f sumrule at each positive momenta:
|
||||
Vect_DP Sum_omega_MEsq (0.0, iKmax - iKmin + 1);
|
||||
|
||||
DP Sum_MEsq = 0.0;
|
||||
|
||||
DP omega, ME;
|
||||
int iK;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
int nr, nl;
|
||||
|
||||
// Read the weights from the ensembles file:
|
||||
LiebLin_Diagonal_State_Ensemble ensemble;
|
||||
|
||||
stringstream ensfilestrstream;
|
||||
//ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
|
||||
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
|
||||
string ensfilestr = ensfilestrstream.str();
|
||||
const char* ensfile_Cstr = ensfilestr.c_str();
|
||||
|
||||
ensemble.Load(c_int, L, N, ensfile_Cstr);
|
||||
|
||||
for (int ns = 0; ns < ensemble.nstates; ++ns) {
|
||||
|
||||
// Define the raw input file name:
|
||||
stringstream filenameprefix;
|
||||
//Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, kBT, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
|
||||
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
|
||||
string prefix = filenameprefix.str();
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
|
||||
ifstream infile;
|
||||
infile.open(RAW_Cstr);
|
||||
if(infile.fail()) {
|
||||
cout << "Filename RAW_Cstr = " << RAW_Cstr << endl;
|
||||
JSCerror("Could not open input file in Evaluate_F_Sumrule(LiebLin...).");
|
||||
}
|
||||
|
||||
while (infile.peek() != EOF) {
|
||||
infile >> omega >> iK >> ME >> dev >> label;
|
||||
if (whichDSF == '1') infile >> nr >> nl;
|
||||
//if (iK > 0 && iK <= iK_UL) Sum_omega_MEsq[iK] += omega * MEsq;
|
||||
if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += ensemble.weight[ns] * omega * ME * ME;
|
||||
Sum_MEsq += ensemble.weight[ns] * ME * ME;
|
||||
}
|
||||
|
||||
infile.close();
|
||||
}
|
||||
|
||||
LiebLin_Bethe_State RefState = ensemble.state[0]; // to use the code below, which comes from earlier Evaluate_F_Sumrule
|
||||
|
||||
ofstream outfile;
|
||||
outfile.open(FSR_Cstr);
|
||||
outfile.precision(16);
|
||||
|
||||
if (whichDSF == 'd' || whichDSF == '1') {
|
||||
/*
|
||||
outfile << 0 << "\t" << 1; // full saturation at k = 0 !
|
||||
for (int i = 1; i <= iK_UL; ++i)
|
||||
outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L * RefState.L
|
||||
* RefState.L * RefState.L/(4.0 * PI * PI * i * i * RefState.N);
|
||||
*/
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
if (i > iKmin) outfile << endl;
|
||||
//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * JSC::max(abs(i), 1), 2.0) * RefState.N);
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * JSC::max(abs(i), 1), 2.0) * RefState.N)
|
||||
// Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
|
||||
// so -iK is at index index(-iK) = -iK - iKmin
|
||||
// We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
|
||||
<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
|
||||
0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin])
|
||||
: Sum_omega_MEsq[i - iKmin])
|
||||
* pow(RefState.L, 4.0)/(pow(2.0 * PI * JSC::max(abs(i), 1), 2.0) * RefState.N);
|
||||
}
|
||||
}
|
||||
else if (whichDSF == 'g' || whichDSF == 'o') {
|
||||
/*
|
||||
for (int i = 0; i <= iK_UL; ++i)
|
||||
outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L
|
||||
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
//cout << "Sum_MEsq = " << Sum_MEsq << "\tN/L = " << RefState.N/RefState.L << endl;
|
||||
*/
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
if (i > iKmin) outfile << endl;
|
||||
//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
|
||||
///((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
|
||||
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
|
||||
<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
|
||||
0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin]) : Sum_omega_MEsq[i - iKmin])
|
||||
* RefState.L/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
}
|
||||
}
|
||||
|
||||
outfile.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,536 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Tgt0.cc
|
||||
|
||||
Purpose: Finite temperature correlations for Lieb-Liniger
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
|
||||
/*
|
||||
DP Entropy (LiebLin_Bethe_State& RefState, DP epsilon)
|
||||
{
|
||||
// This function calculates the entropy of a finite Lieb-Liniger state,
|
||||
// using the quantum number space particle and hole densities.
|
||||
|
||||
// The densities are a sum of Gaussians with width epsilon.
|
||||
|
||||
// We calculate \rho (x) and \rho_h (x) for x_j on a fine lattice.
|
||||
|
||||
int Ix2max = RefState.Ix2.max();
|
||||
int Ix2min = RefState.Ix2.min();
|
||||
|
||||
//cout << Ix2max << "\t" << Ix2min << endl;
|
||||
|
||||
// Give a bit of room for leftmost and rightmost particles Gaussians to attain asymptotic values:
|
||||
Ix2max += int(10.0 * RefState.L * epsilon);
|
||||
Ix2min -= int(10.0 * RefState.L * epsilon);
|
||||
|
||||
//cout << Ix2max << "\t" << Ix2min << endl;
|
||||
|
||||
DP xmax = Ix2max/(2.0* RefState.L);
|
||||
DP xmin = Ix2min/(2.0* RefState.L);
|
||||
|
||||
//xmax += 10.0* epsilon;
|
||||
//xmin -= 10.0* epsilon;
|
||||
|
||||
DP dx = 0.1/RefState.L;
|
||||
int Nptsx = int((xmax - xmin)/dx);
|
||||
|
||||
Vect<bool> occupied (false, (Ix2max - Ix2min)/2 + 1); // whether there is a particle or not
|
||||
for (int i = 0; i < RefState.N; ++i) occupied[(RefState.Ix2[i] - Ix2min)/2] = true;
|
||||
|
||||
Vect<double> rho(0.0, Nptsx);
|
||||
Vect<double> rhoh(0.0, Nptsx);
|
||||
|
||||
//cout << xmin << "\t" << xmax << "\t" << dx << "\t" << Nptsx << endl;
|
||||
|
||||
DP x;
|
||||
DP epsilonsq = epsilon * epsilon;
|
||||
DP twoepsilonsq = 2.0 * epsilon * epsilon;
|
||||
|
||||
//Vect<DP> xparticle(RefState.N);
|
||||
//for (int i = 0; i < RefState.N; ++i) xparticle[i] = RefState.Ix2[i]/(2.0* RefState.L);
|
||||
Vect<DP> xarray((Ix2max - Ix2min)/2 + 1);
|
||||
for (int i = 0; i < (Ix2max - Ix2min)/2 + 1; ++i) xarray[i] = (0.5*Ix2min + i)/RefState.L;
|
||||
|
||||
for (int ix = 0; ix < Nptsx; ++ix) {
|
||||
x = xmin + dx * (ix + 0.5);
|
||||
//for (int i = 0; i < RefState.N; ++i) rho[ix] += 1.0/((x - xparticle[i]) * (x - xparticle[i]) + epsilonsq);
|
||||
//rho[ix] *= epsilon/(PI * RefState.L);
|
||||
for (int i = 0; i < (Ix2max - Ix2min)/2 + 1; ++i) {
|
||||
// Using Gaussians:
|
||||
//if (occupied[i]) rho[ix] += exp(-(x - xarray[i]) * (x - xarray[i])/twoepsilonsq);
|
||||
//else rhoh[ix] += exp(-(x - xarray[i]) * (x - xarray[i])/twoepsilonsq);
|
||||
// Using Lorentzians:
|
||||
if (occupied[i]) rho[ix] += 1.0/((x - xarray[i]) * (x - xarray[i]) + epsilonsq);
|
||||
else rhoh[ix] += 1.0/((x - xarray[i]) * (x - xarray[i]) + epsilonsq);
|
||||
}
|
||||
//rho[ix] /= sqrt(twoPI) * epsilon * RefState.L;
|
||||
//rhoh[ix] /= sqrt(twoPI) * epsilon * RefState.L;
|
||||
rho[ix] *= epsilon/(PI * RefState.L);
|
||||
rhoh[ix] *= epsilon/(PI * RefState.L);
|
||||
//cout << ix << " x = " << x << "\trho = " << rho[ix] << "\trhoh = " << rhoh[ix] << "\trho + rhoh = " << rho[ix] + rhoh[ix] << endl;
|
||||
}
|
||||
|
||||
// Now calculate the entropy:
|
||||
complex<DP> entropy = 0.0;
|
||||
DP Deltax = log(RefState.L)/RefState.L;
|
||||
for (int ix = 0; ix < Nptsx; ++ix)
|
||||
//entropy -= ln_Gamma (1.0 + rho[ix]) + ln_Gamma (2.0 - rho[ix]); // This is ln (\rho_tot choose \rho) with \rho_tot = 1.
|
||||
entropy += ln_Gamma (RefState.L * (rho[ix] + rhoh[ix]) * Deltax + 1.0) - ln_Gamma(RefState.L * rho[ix] * Deltax + 1.0) - ln_Gamma (RefState.L * rhoh[ix] * Deltax + 1.0); // This is ln (\rho_tot choose \rho) with \rho_tot = 1.
|
||||
entropy *= dx/Deltax;
|
||||
|
||||
//cout << "Entropy found " << entropy << "\t" << real(entropy) << endl;
|
||||
|
||||
return(real(entropy));
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
DP Entropy_rho (LiebLin_Bethe_State& RefState, int Delta)
|
||||
{
|
||||
// This function calculates the discrete entropy of a finite Lieb-Liniger state,
|
||||
// counting the possible permutations within windows of fixed width.
|
||||
|
||||
// We assume that the quantum numbers are ordered.
|
||||
|
||||
// Calculate a density \rho_\Delta (x) for x_j on the lattice:
|
||||
|
||||
int iK_UL = JSC::max(RefState.Ix2[0], RefState.Ix2[RefState.N - 1]);
|
||||
|
||||
Vect<double> rhoD(0.0, 2* iK_UL);
|
||||
|
||||
int fourDeltasq = 4 * Delta * Delta;
|
||||
for (int ix = 0; ix < 2* iK_UL; ++ix) {
|
||||
// x = (-iK_UL + 1/2 + ix)/L
|
||||
for (int i = 0; i < RefState.N; ++i) rhoD[ix] += 1.0/((-2*iK_UL + 1 + 2*ix -RefState.Ix2[i]) * (-2*iK_UL + 1 + 2*ix -RefState.Ix2[i]) + fourDeltasq);
|
||||
rhoD[ix] *= 4.0 * Delta/PI;
|
||||
//cout << "x = " << (-iK_UL + 1/2 + ix)/RefState.L << "\trhoD = " << rhoD[ix] << endl;
|
||||
}
|
||||
|
||||
// Now calculate the entropy:
|
||||
DP entropy = 0.0;
|
||||
for (int ix = 0; ix < 2* iK_UL; ++ix)
|
||||
entropy -= rhoD[ix] * log(rhoD[ix]) + (1.0 - rhoD[ix]) * log(1.0 - rhoD[ix]);
|
||||
|
||||
return(entropy);
|
||||
}
|
||||
*/
|
||||
|
||||
DP Entropy_Fixed_Delta (LiebLin_Bethe_State& RefState, int Delta)
|
||||
{
|
||||
// This function calculates the discrete entropy of a finite Lieb-Liniger state,
|
||||
// counting the possible permutations within windows of fixed width.
|
||||
|
||||
// We assume that the quantum numbers are ordered.
|
||||
|
||||
// Fill in vector of occupancies:
|
||||
int nrIs = (RefState.Ix2[RefState.N-1] - RefState.Ix2[0])/2 + 1 + 2*Delta; // assume Ix2 are ordered, leave space of Delta on both sides
|
||||
Vect<int> occupancy(0, nrIs); // leave space of Delta on both sides
|
||||
for (int i = 0; i < RefState.N; ++i) occupancy[Delta + (RefState.Ix2[i] -RefState.Ix2[0])/2] = 1;
|
||||
// Check:
|
||||
int ncheck = 0;
|
||||
for (int i = 0; i < nrIs; ++i) if(occupancy[i] == 1) ncheck++;
|
||||
//cout << "Check occupancy: " << endl << occupancy << endl;
|
||||
if (ncheck != RefState.N) {
|
||||
cout << ncheck << "\t" << RefState.N << endl;
|
||||
JSCerror("Counting q numbers incorrectly in Entropy.");
|
||||
}
|
||||
|
||||
// Define some useful numbers:
|
||||
Vect_DP oneoverDeltalnchoose(Delta + 1);
|
||||
for (int i = 0; i <= Delta; ++i) oneoverDeltalnchoose[i] = ln_choose(Delta, i)/Delta;
|
||||
//Vect_DP oneoverDeltalnchoosecheck(Delta + 1);
|
||||
//for (int i = 0; i <= Delta; ++i) oneoverDeltalnchoosecheck[i] = log(DP(choose(Delta, i)))/Delta;
|
||||
//cout << oneoverDeltalnchoose << endl;
|
||||
//cout << oneoverDeltalnchoosecheck << endl;
|
||||
|
||||
// Compute entropy:
|
||||
DP entropy = 0.0;
|
||||
int np;
|
||||
for (int i = 0; i < nrIs - Delta; ++i) {
|
||||
np = 0;
|
||||
for (int iD = 0; iD < Delta; ++iD) if (occupancy[i + iD] == 1) np++;
|
||||
|
||||
entropy += oneoverDeltalnchoose[np];
|
||||
}
|
||||
|
||||
return(entropy);
|
||||
}
|
||||
|
||||
DP Entropy (LiebLin_Bethe_State& RefState, int Delta)
|
||||
{
|
||||
// Perform an average of entropies for regulators from Delta to 2Delta:
|
||||
DP entropysum = 0.0;
|
||||
for (int ie = 0; ie < Delta; ++ie) entropysum += Entropy_Fixed_Delta (RefState, Delta + ie);
|
||||
return(entropysum/Delta);
|
||||
}
|
||||
|
||||
DP Entropy (LiebLin_Bethe_State& RefState)
|
||||
{
|
||||
int Delta = int(log(RefState.L));
|
||||
return(Entropy (RefState, Delta));
|
||||
}
|
||||
/*
|
||||
DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, int Delta)
|
||||
{
|
||||
return(RefState.E - kBT * Entropy (RefState, Delta));
|
||||
}
|
||||
|
||||
DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, int Delta)
|
||||
{
|
||||
return(RefState.E - kBT * Entropy (RefState, Delta));
|
||||
}
|
||||
*/
|
||||
DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT)
|
||||
{
|
||||
return(RefState.E - kBT * Entropy (RefState));
|
||||
}
|
||||
|
||||
/*
|
||||
//LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, int Delta)
|
||||
LiebLin_Bethe_State Canonical_Saddle_Point_State_pre20110618 (DP c_int, DP L, int N, DP kBT, DP epsilon)
|
||||
{
|
||||
// This function returns the discretized state minimizing the canonical free energy
|
||||
// F = E - T S.
|
||||
|
||||
LiebLin_Bethe_State spstate(c_int, L, N);
|
||||
spstate.Compute_All (true);
|
||||
|
||||
if (kBT < 1.0e-3) return(spstate); // interpret as zero T case
|
||||
|
||||
LiebLin_Bethe_State spstateup = spstate;
|
||||
LiebLin_Bethe_State spstatedown = spstate;
|
||||
|
||||
bool converged = false;
|
||||
bool convergedati = false;
|
||||
|
||||
DP canfreeenstay, canfreeenup, canfreeendown;
|
||||
DP Estay, Eup, Edown;
|
||||
DP Sstay, Sup, Sdown;
|
||||
|
||||
while (!converged) {
|
||||
|
||||
spstate.Compute_All (false);
|
||||
converged = true; // set to false if we change anything
|
||||
|
||||
// If we can minimize the free energy by changing the quantum number, we do:
|
||||
// NOTE: we keep the state symmetric w/r to parity.
|
||||
|
||||
for (int i = 0; i < N/2; ++i) {
|
||||
// Try to increase or decrease this quantum number
|
||||
|
||||
convergedati = false;
|
||||
|
||||
while (!convergedati) {
|
||||
|
||||
convergedati = true; // set to false if we change anything
|
||||
|
||||
Estay = spstate.E;
|
||||
//Sstay = Entropy (spstate, Delta);
|
||||
Sstay = Entropy (spstate, epsilon);
|
||||
//canfreeenstay = Canonical_Free_Energy (spstate, kBT, Delta);
|
||||
canfreeenstay = Estay - kBT * Sstay;
|
||||
|
||||
spstateup = spstate;
|
||||
if (i == 0 || spstateup.Ix2[i-1] < spstateup.Ix2[i] - 2) {
|
||||
spstateup.Ix2[i] -= 2;
|
||||
spstateup.Ix2[N-1-i] += 2;
|
||||
spstateup.Compute_All(false);
|
||||
Eup = spstateup.E;
|
||||
//Sup = Entropy(spstateup, Delta);
|
||||
Sup = Entropy(spstateup, epsilon);
|
||||
//canfreeenup = Canonical_Free_Energy (spstateup, kBT, Delta);
|
||||
canfreeenup = Eup - kBT * Sup;
|
||||
}
|
||||
else canfreeenup = canfreeenstay + 1.0e-6;
|
||||
|
||||
spstatedown = spstate;
|
||||
if (spstatedown.Ix2[i+1] > spstatedown.Ix2[i] + 2) {
|
||||
spstatedown.Ix2[i] += 2;
|
||||
spstatedown.Ix2[N-1-i] -= 2;
|
||||
spstatedown.Compute_All(false);
|
||||
Edown = spstatedown.E;
|
||||
//Sdown = Entropy(spstatedown, Delta);
|
||||
Sdown = Entropy(spstatedown, epsilon);
|
||||
//canfreeendown = Canonical_Free_Energy (spstatedown, kBT, Delta);
|
||||
canfreeendown = Edown - kBT * Sdown;
|
||||
}
|
||||
else canfreeendown = canfreeenstay + 1.0e-6;
|
||||
|
||||
//cout << "i = " << i << "\t" << spstate.Ix2[i] << "\t\t" << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown
|
||||
// << "\t\t" << Estay << "\t" << Eup << "\t" << Edown << "\t\t" << Sstay << "\t" << Sup << "\t" << Sdown << endl;
|
||||
// Choose what to do:
|
||||
if (canfreeenup < canfreeenstay && canfreeendown < canfreeenstay)
|
||||
cout << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown << "\tWarning: unclear option for minimization." << endl;
|
||||
else if (canfreeenup < canfreeenstay) {
|
||||
spstate = spstateup;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
else if (canfreeendown < canfreeenstay) {
|
||||
spstate = spstatedown;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
// else do nothing.
|
||||
} // while !convergedati
|
||||
|
||||
} // for i
|
||||
} // while (!converged)
|
||||
|
||||
return(spstate);
|
||||
}
|
||||
*/
|
||||
|
||||
/* REMOVED FROM ++G_3 ONWARDS
|
||||
//LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, int Delta)
|
||||
//LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, DP epsilon)
|
||||
LiebLin_Bethe_State Canonical_Saddle_Point_State_pre8 (DP c_int, DP L, int N, DP kBT)
|
||||
{
|
||||
// This function returns the discretized state minimizing the canonical free energy
|
||||
// F = E - T S.
|
||||
|
||||
// Improvement on version pre20110618: allow for pairwise `in' and `out' movements
|
||||
// keeping the energy the same to order 1/L^2 but changing the entropy.
|
||||
|
||||
// The regulator Delta also has become an `internal' parameter.
|
||||
|
||||
LiebLin_Bethe_State spstate(c_int, L, N);
|
||||
spstate.Compute_All (true);
|
||||
|
||||
if (kBT < 1.0e-3) return(spstate); // interpret as zero T case
|
||||
|
||||
LiebLin_Bethe_State spstateup = spstate;
|
||||
LiebLin_Bethe_State spstatedown = spstate;
|
||||
LiebLin_Bethe_State spstatein = spstate;
|
||||
LiebLin_Bethe_State spstateout = spstate;
|
||||
|
||||
bool converged = false;
|
||||
bool convergedati = false;
|
||||
|
||||
DP canfreeenstay, canfreeenup, canfreeendown, canfreeenin, canfreeenout;
|
||||
DP Estay, Eup, Edown, Ein, Eout;
|
||||
DP Sstay, Sup, Sdown, Sin, Sout;
|
||||
Estay = 0.0; Eup = 0.0; Edown = 0.0; Ein = 0.0; Eout = 0.0;
|
||||
Sstay = 0.0; Sup = 0.0; Sdown = 0.0; Sin = 0.0; Sout = 0.0;
|
||||
|
||||
while (!converged) {
|
||||
|
||||
spstate.Compute_All (false);
|
||||
converged = true; // set to false if we change anything
|
||||
|
||||
// If we can minimize the free energy by changing the quantum number, we do:
|
||||
// NOTE: we keep the state symmetric w/r to parity.
|
||||
|
||||
for (int i = 0; i < N/2 - 1; ++i) {
|
||||
|
||||
// Try to increase or decrease the quantum numbers at i ,
|
||||
// or do an (approximately) energy-preserving move with i+1 (and parity pairs)
|
||||
// giving 5 possible options: stay same, (\pm 1, 0), (+1, -1), (-1, +1)
|
||||
|
||||
convergedati = false;
|
||||
|
||||
while (!convergedati) {
|
||||
|
||||
convergedati = true; // set to false if we change anything
|
||||
|
||||
Estay = spstate.E;
|
||||
Sstay = Entropy (spstate);
|
||||
//Sstay = Entropy (spstate, Delta);
|
||||
//Sstay = Entropy (spstate, epsilon);
|
||||
//canfreeenstay = Canonical_Free_Energy (spstate, kBT, Delta);
|
||||
canfreeenstay = Estay - kBT * Sstay;
|
||||
|
||||
spstateup = spstate;
|
||||
if (i == 0 || spstateup.Ix2[i-1] < spstateup.Ix2[i] - 2) {
|
||||
spstateup.Ix2[i] -= 2;
|
||||
spstateup.Ix2[N-1-i] += 2;
|
||||
spstateup.Compute_All(false);
|
||||
Eup = spstateup.E;
|
||||
Sup = Entropy(spstateup);
|
||||
//Sup = Entropy(spstateup, Delta);
|
||||
//Sup = Entropy(spstateup, epsilon);
|
||||
//canfreeenup = Canonical_Free_Energy (spstateup, kBT, Delta);
|
||||
canfreeenup = Eup - kBT * Sup;
|
||||
}
|
||||
else canfreeenup = canfreeenstay + 1.0e-6;
|
||||
|
||||
spstatedown = spstate;
|
||||
if (spstatedown.Ix2[i+1] > spstatedown.Ix2[i] + 2) {
|
||||
spstatedown.Ix2[i] += 2;
|
||||
spstatedown.Ix2[N-1-i] -= 2;
|
||||
spstatedown.Compute_All(false);
|
||||
Edown = spstatedown.E;
|
||||
Sdown = Entropy(spstatedown);
|
||||
//Sdown = Entropy(spstatedown, Delta);
|
||||
//Sdown = Entropy(spstatedown, epsilon);
|
||||
//canfreeendown = Canonical_Free_Energy (spstatedown, kBT, Delta);
|
||||
canfreeendown = Edown - kBT * Sdown;
|
||||
}
|
||||
else canfreeendown = canfreeenstay + 1.0e-6;
|
||||
|
||||
spstatein = spstate;
|
||||
if (spstatein.Ix2[i+1] > spstatein.Ix2[i] + 4) { // can move them closer
|
||||
spstatein.Ix2[i] += 2;
|
||||
spstatein.Ix2[i+1] -= 2;
|
||||
spstatein.Ix2[N-1-i] -= 2;
|
||||
spstatein.Ix2[N-1-i-1] += 2;
|
||||
spstatein.Compute_All(false);
|
||||
Ein = spstatein.E;
|
||||
Sin = Entropy(spstatein);
|
||||
//Sin = Entropy(spstatein, Delta);
|
||||
//Sin = Entropy(spstatein, epsilon);
|
||||
//canfreeenin = Canonical_Free_Energy (spstatein, kBT, Delta);
|
||||
canfreeenin = Ein - kBT * Sin;
|
||||
}
|
||||
else canfreeenin = canfreeenstay + 1.0e-6;
|
||||
|
||||
spstateout = spstate;
|
||||
if (i == 0 && spstateout.Ix2[1] + 2 < spstateout.Ix2[2]
|
||||
|| (i < N/2 - 1 && spstateout.Ix2[i] - 2 > spstateout.Ix2[i-1]
|
||||
&& spstateout.Ix2[i+1] + 2 < spstateout.Ix2[i+2])) { // can move them further apart
|
||||
spstateout.Ix2[i] -= 2;
|
||||
spstateout.Ix2[i+1] += 2;
|
||||
spstateout.Ix2[N-1-i] += 2;
|
||||
spstateout.Ix2[N-1-i-1] -= 2;
|
||||
spstateout.Compute_All(false);
|
||||
Eout = spstateout.E;
|
||||
Sout = Entropy(spstateout);
|
||||
//Sout = Entropy(spstateout, Delta);
|
||||
//Sout = Entropy(spstateout, epsilon);
|
||||
//canfreeenout = Canonical_Free_Energy (spstateout, kBT, Delta);
|
||||
canfreeenout = Eout - kBT * Sout;
|
||||
}
|
||||
else canfreeenout = canfreeenstay + 1.0e-6;
|
||||
|
||||
//cout << setprecision(8) << "i = " << i << "\t" << spstate.Ix2[i] << "\t" << spstate.Ix2[i+1] << "\t\t" << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown << "\t" << canfreeenin << "\t" << canfreeenout << endl;
|
||||
//cout << "\t\tE: " << Estay << "\t" << Eup << "\t" << Edown << "\t" << Ein << "\t" << Eout << endl;
|
||||
//cout << "\t\tS: " << Sstay << "\t" << Sup << "\t" << Sdown << "\t" << Sin << "\t" << Sout << endl;
|
||||
|
||||
// Choose what to do: find minimum,
|
||||
if (canfreeenstay < canfreeenup && canfreeenstay < canfreeendown && canfreeenstay < canfreeenin && canfreeenstay < canfreeenout) {
|
||||
// do nothing, convergetati is already true
|
||||
}
|
||||
else if (canfreeenup < canfreeenstay && canfreeenup < canfreeendown && canfreeenup < canfreeenin && canfreeenup < canfreeenout) {
|
||||
spstate = spstateup;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
else if (canfreeendown < canfreeenstay && canfreeendown < canfreeenup && canfreeendown < canfreeenin && canfreeendown < canfreeenout) {
|
||||
spstate = spstatedown;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
else if (canfreeenin < canfreeenstay && canfreeenin < canfreeenup && canfreeenin < canfreeendown && canfreeenin < canfreeenout) {
|
||||
spstate = spstatein;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
else if (canfreeenout < canfreeenstay && canfreeenout < canfreeenup && canfreeenout < canfreeendown && canfreeenout < canfreeenin) {
|
||||
spstate = spstateout;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
else cout << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown << "\t" << canfreeenin << "\t" << canfreeenout << "\tWarning: unclear option for minimization." << endl;
|
||||
|
||||
// else do nothing.
|
||||
} // while !convergedati
|
||||
|
||||
} // for i
|
||||
} // while (!converged)
|
||||
|
||||
//cout << "Number of holes between I's: " << endl;
|
||||
//for (int i = 0; i < N/2; ++i) cout << (spstate.Ix2[i+1] - spstate.Ix2[i])/2 - 1 << "\t";
|
||||
//cout << endl;
|
||||
|
||||
return(spstate);
|
||||
}
|
||||
*/
|
||||
|
||||
DP rho_of_lambdaoc_1 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta)
|
||||
{
|
||||
DP answer = 0.0;
|
||||
for (int i = 0; i < RefState.N; ++i)
|
||||
answer += atan((lambdaoc - RefState.lambdaoc[i])/delta + 0.5) - atan((lambdaoc - RefState.lambdaoc[i])/delta - 0.5);
|
||||
answer *= 1.0/(PI * delta * RefState.L);
|
||||
|
||||
return(answer);
|
||||
}
|
||||
|
||||
DP rho_of_lambdaoc_2 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta)
|
||||
{
|
||||
DP answer = 0.0;
|
||||
for (int i = 0; i < RefState.N; ++i)
|
||||
answer += 1.0/(pow(lambdaoc - RefState.lambdaoc[i], 2.0) + delta*delta);
|
||||
answer *= delta/(PI * RefState.L);
|
||||
|
||||
return(answer);
|
||||
}
|
||||
|
||||
// Better implementation: making use of rediscretized TBA state.
|
||||
LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT)
|
||||
{
|
||||
// This function returns the discretized state minimizing the canonical free energy
|
||||
// F = E - T S.
|
||||
|
||||
// This is obtained by rediscretizing the solution coming from TBA.
|
||||
|
||||
// ASSUMPTIONS:
|
||||
// Periodic boundary conditions (the state which is output is forced to be symmetric Ix2 == -Ix2).
|
||||
|
||||
// For zero temperature, return the ground state:
|
||||
if (fabs(kBT) < 1.0e-4) return(LiebLin_Bethe_State(c_int, L, N));
|
||||
|
||||
// Otherwise, return the discretized TBA saddle-point state:
|
||||
LiebLin_TBA_Solution TBAsol = LiebLin_TBA_Solution_fixed_nbar (c_int, N/L, kBT, 1.0e-4, JSC::max(N/10, 10));
|
||||
|
||||
LiebLin_Bethe_State spstate = Discretized_LiebLin_Bethe_State (c_int, L, N, TBAsol.rho);
|
||||
|
||||
// Explicitly symmetrize:
|
||||
for (int i = 0; i < N/2; ++i) spstate.Ix2[i] = -spstate.Ix2[N-1-i];
|
||||
spstate.Compute_All(false);
|
||||
|
||||
return(spstate);
|
||||
}
|
||||
|
||||
LiebLin_Bethe_State Add_Particle_at_Center (const LiebLin_Bethe_State& RefState)
|
||||
{
|
||||
LiebLin_Bethe_State ReturnState (RefState.c_int, RefState.L, RefState.N + 1);
|
||||
|
||||
// Add a quantum number in middle (explicitly: to right of index N/2)
|
||||
// and shift quantum numbers by half-integer away from added one:
|
||||
ReturnState.Ix2[RefState.N/2] = RefState.Ix2[RefState.N/2] - 1;
|
||||
for (int i = 0; i < RefState.N+1; ++i)
|
||||
ReturnState.Ix2[i + (i >= RefState.N/2)] = RefState.Ix2[i] - 1 + 2*(i >= RefState.N/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
LiebLin_Bethe_State Remove_Particle_at_Center (const LiebLin_Bethe_State& RefState)
|
||||
{
|
||||
LiebLin_Bethe_State ReturnState (RefState.c_int, RefState.L, RefState.N - 1);
|
||||
|
||||
// Remove midmost and shift quantum numbers by half-integer towards removed one:
|
||||
for (int i = 0; i < RefState.N-1; ++i)
|
||||
ReturnState.Ix2[i] = RefState.Ix2[i + (i >= RefState.N/2)] + 1 - 2*(i >= RefState.N/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,117 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Twisted_ln_Overlap.cc
|
||||
|
||||
Purpose: Calculates Nikita Slavnov's determinant, case RHS is Bethe
|
||||
and LHS is twisted Bethe
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
complex<DP> Kernel_Twisted (complex<DP> expbeta, complex<DP> lambdaoc)
|
||||
{
|
||||
return(1.0/(lambdaoc + II) - expbeta/(lambdaoc - II));
|
||||
}
|
||||
|
||||
complex<DP> Kernel_Twisted (complex<DP> expbeta, DP lambdaoc)
|
||||
{
|
||||
return(1.0/(lambdaoc + II) - expbeta/(lambdaoc - II));
|
||||
}
|
||||
|
||||
complex<DP> Fn_V (int j, int sign, Vect<complex<DP> >& lstate_lambdaoc, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
complex<DP> result_num = 1.0;
|
||||
complex<DP> result_den = 1.0;
|
||||
|
||||
complex<DP> signcx = complex<DP>(sign);
|
||||
|
||||
for (int m = 0; m < rstate.N; ++m) {
|
||||
result_num *= (lstate_lambdaoc[m] - rstate.lambdaoc[j] + signcx * II);
|
||||
result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + signcx * II);
|
||||
}
|
||||
|
||||
return(result_num/result_den);
|
||||
}
|
||||
|
||||
complex<DP> Fn_V_Nikita (int j, int sign, Vect<complex<DP> >& lstate_lambdaoc, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
// To match with Nikita's new conventions
|
||||
return(1.0/Fn_V (j, -sign, lstate_lambdaoc, rstate));
|
||||
}
|
||||
|
||||
complex<DP> LiebLin_Twisted_ln_Overlap (DP expbeta, Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
Vect<complex<DP> > lstate_lambdaoc_CX(lstate_lambdaoc.size());
|
||||
for (int i = 0; i < lstate_lambdaoc.size(); ++i) lstate_lambdaoc_CX[i] = complex<DP>(lstate_lambdaoc[i]);
|
||||
return(LiebLin_Twisted_ln_Overlap (complex<DP>(expbeta), lstate_lambdaoc_CX, lstate_lnnorm, rstate));
|
||||
}
|
||||
|
||||
complex<DP> LiebLin_Twisted_ln_Overlap (complex<DP> expbeta, Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
// Computes the log of the overlap between the left state and the Bethe rstate
|
||||
|
||||
// If momentum difference is zero but states are different, then form factor is zero:
|
||||
|
||||
SQMat_CX one_plus_U (0.0, rstate.N);
|
||||
|
||||
Vect_CX Vplus_Nikita (0.0, rstate.N); // contains V^+_j
|
||||
Vect_CX Vminus_Nikita (0.0, rstate.N); // contains V^-_j
|
||||
Vect_CX Fn_Prod (0.0, rstate.N); // product_{m\neq j} (\mu_m - \lambda_j)/(\lambda_m - \lambda_j)
|
||||
Vect_CX rKern (0.0, rstate.N); // K(lambda_j - lambda_p)
|
||||
|
||||
int p = 0;
|
||||
|
||||
complex<DP> Kout = lstate_lambdaoc.sum() - rstate.K;
|
||||
|
||||
for (int a = 0; a < rstate.N; ++a) {
|
||||
Vplus_Nikita[a] = Fn_V_Nikita (a, 1, lstate_lambdaoc, rstate);
|
||||
Vminus_Nikita[a] = Fn_V_Nikita (a, -1, lstate_lambdaoc, rstate);
|
||||
Fn_Prod[a] = 1.0;
|
||||
for (int m = 0; m < rstate.N; ++m)
|
||||
if (m != a) Fn_Prod[a] *= (lstate_lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
|
||||
//rKern[a] = rstate.Kernel (a, p);
|
||||
rKern[a] = Kernel_Twisted (expbeta, rstate.lambdaoc[p] - rstate.lambdaoc[a]);
|
||||
}
|
||||
|
||||
for (int a = 0; a < rstate.N; ++a)
|
||||
for (int b = 0; b < rstate.N; ++b)
|
||||
one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + ((lstate_lambdaoc[a] - rstate.lambdaoc[a])/(1.0/Vplus_Nikita[a] - 1.0/Vminus_Nikita[a]))
|
||||
* Fn_Prod[a] * (Kernel_Twisted(expbeta, rstate.lambdaoc[a] - rstate.lambdaoc[b]) - rKern[b]);
|
||||
|
||||
complex<DP> ln_ddalpha_sigma = lndet_LU_CX_dstry(one_plus_U);
|
||||
|
||||
complex<DP> ln_prod_V = 0.0;
|
||||
for (int a = 0; a < rstate.N; ++a) ln_prod_V += log(expbeta * Vplus_Nikita[a]/Vminus_Nikita[a] - 1.0);
|
||||
ln_prod_V -= 0.5 * rstate.N * log(expbeta);
|
||||
|
||||
complex<DP> ln_prod_2 = 0.0;
|
||||
for (int a = 0; a < rstate.N; ++a)
|
||||
for (int b = 0; b < rstate.N; ++b)
|
||||
ln_prod_2 += log((lstate_lambdaoc[a] - rstate.lambdaoc[b] - II)/(rstate.lambdaoc[a] - lstate_lambdaoc[b]));
|
||||
|
||||
//cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << endl;
|
||||
//cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(Vplus[p] - Vminus[p]) << endl;
|
||||
|
||||
ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(Vplus_Nikita[p] - expbeta * Vminus_Nikita[p]);
|
||||
|
||||
//cout << "shift = " << (complex<DP>(rstate.N) * (lstate_lambdaoc[0] - rstate.lambdaoc[0])/twoPI) << "\tKout = " << Kout << "\texp(-II*Kout) = " << exp(-II * Kout)
|
||||
// << "\tlog(exp(-II * Kout) - 1.0) = " << log(exp(-II * Kout) - 1.0) << endl;
|
||||
//cout << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << lstate_lnnorm << endl << endl;
|
||||
|
||||
//return (log(1.0 - expbeta) + ln_ddalpha_sigma - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
return (log(1.0 - exp(-II * Kout)) + ln_ddalpha_sigma - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Gaudin_lnnorm.cc
|
||||
|
||||
Purpose: calculates the Gaudin norm of a vector of arbitrary
|
||||
complex rapidities
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
DP LiebLin_Twisted_lnnorm (Vect<complex<DP> >& lambdaoc, double cxL)
|
||||
{
|
||||
// Calculates the lnnorm of an eigenstate of the twisted transfer matrix
|
||||
// so Gaudin can be used.
|
||||
|
||||
int N = lambdaoc.size();
|
||||
|
||||
SQMat<complex<DP> > Gaudin(N);
|
||||
|
||||
complex<DP> sum_Kernel = 0.0;
|
||||
|
||||
for (int j = 0; j < N; ++j)
|
||||
for (int k = 0; k < N; ++k) {
|
||||
if (j == k) {
|
||||
sum_Kernel = 0.0;
|
||||
for (int kp = 0; kp < N; ++kp) if (j != kp) sum_Kernel += 2.0/((lambdaoc[j] - lambdaoc[kp]) * (lambdaoc[j] - lambdaoc[kp]) + 1.0);
|
||||
Gaudin[j][k] = cxL + sum_Kernel;
|
||||
}
|
||||
else Gaudin[j][k] = - 2.0/((lambdaoc[j] - lambdaoc[k]) * (lambdaoc[j] - lambdaoc[k]) + 1.0);
|
||||
}
|
||||
|
||||
DP lnnorm = real(lndet_LU_CX_dstry(Gaudin));
|
||||
|
||||
// Add the pieces outside of Gaudin determinant
|
||||
for (int j = 0; j < N - 1; ++j) for (int k = j+1; k < N; ++k) lnnorm += log(1.0 + 1.0/norm(lambdaoc[j] - lambdaoc[k]));
|
||||
|
||||
return(lnnorm);
|
||||
}
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,108 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Utils.cc
|
||||
|
||||
Purpose: Utilities for Lieb-Liniger gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
DP LiebLin_dE0_dc (DP c_int, DP L, int N)
|
||||
{
|
||||
LiebLin_Bethe_State groundstate (c_int, L, N);
|
||||
groundstate.Compute_All(true);
|
||||
|
||||
DP dc_int = 1.0e-5 * c_int;
|
||||
LiebLin_Bethe_State groundstate_2 (c_int + dc_int, L, N);
|
||||
groundstate_2.Compute_All(true);
|
||||
|
||||
return((groundstate_2.E - groundstate.E)/dc_int);
|
||||
}
|
||||
|
||||
DP LiebLin_vs (DP c_int, DP L, int N)
|
||||
{
|
||||
LiebLin_Bethe_State gstate (c_int, L, N);
|
||||
gstate.Compute_All(true);
|
||||
|
||||
DP Egs = gstate.E;
|
||||
|
||||
gstate.Ix2[N-1] += 2;
|
||||
|
||||
gstate.Compute_All(false);
|
||||
|
||||
return((gstate.E - Egs) * L/twoPI);
|
||||
|
||||
}
|
||||
|
||||
DP LiebLin_Dressed_Charge_N (DP c_int, DP L, int N)
|
||||
{
|
||||
LiebLin_Bethe_State gstate(c_int, L, N);
|
||||
gstate.Compute_All(true);
|
||||
return(twoPI/(c_int * L * (gstate.lambdaoc[N-1] - gstate.lambdaoc[N-2]))); // lambda in units of c within code
|
||||
}
|
||||
|
||||
|
||||
// For computation of threshold exponents:
|
||||
|
||||
int Momentum_Right_Excitations (LiebLin_Bethe_State& ScanState)
|
||||
{
|
||||
// Calculates the momentum of the excitations on the right of Fermi
|
||||
// surface, discarding the rightmost excitation.
|
||||
|
||||
int nr = 0;
|
||||
for (int i = ScanState.N - 2; i >= ScanState.N/2; --i)
|
||||
if (ScanState.Ix2[i] >= 0) nr += (ScanState.Ix2[i] + ScanState.N - 1 - 2*i)/2;
|
||||
|
||||
return(nr);
|
||||
}
|
||||
|
||||
int Momentum_Left_Excitations (LiebLin_Bethe_State& ScanState)
|
||||
{
|
||||
// Calculates the momentum of the excitations on the left of Fermi
|
||||
// surface, discarding the rightmost excitation.
|
||||
|
||||
int nl = 0;
|
||||
for (int i = 0; i < ScanState.N/2; ++i)
|
||||
if (ScanState.Ix2[i] < 0) nl -= (ScanState.Ix2[i] + ScanState.N - 1 - 2*i)/2;
|
||||
|
||||
return(nl);
|
||||
}
|
||||
|
||||
|
||||
DP ln_Overlap_with_BEC (LiebLin_Bethe_State& lambda) // Note: factorial approximated with Lanczos
|
||||
{
|
||||
int N = lambda.N;
|
||||
int L = lambda.L;
|
||||
|
||||
DP c_int = lambda.c_int;
|
||||
|
||||
// The overlap identically vanishes if the state is not parity invariant:
|
||||
if (!lambda.Check_Symmetry()) return(-300.0);
|
||||
|
||||
SQMat_DP Gaudin( N);
|
||||
|
||||
SQMat_DP Gaudin_Quench( N/2);
|
||||
|
||||
lambda.Build_Reduced_Gaudin_Matrix ( Gaudin);
|
||||
lambda.Build_Reduced_BEC_Quench_Gaudin_Matrix (Gaudin_Quench);
|
||||
|
||||
//DP ln_prefactor = N/2.0 * log(2./fabs(c_int*L) ) + 0.5 * (N*log(N) - N + 0.5*log(2. * PI * N));
|
||||
|
||||
DP ln_prefactor = N/2.0 * log(2./(c_int*L) ) + 0.5 * real(ln_Gamma(complex<double>(N+1.0)));
|
||||
|
||||
for(int i =N/2; i<N; i ++) ln_prefactor -= log(fabs(lambda.lambdaoc[i ])) + 0.5*log( 1. + 4. * lambda.lambdaoc[i ]*lambda.lambdaoc[i ]) ;
|
||||
|
||||
//cout << ln_prefactor << endl;
|
||||
return (ln_prefactor + real(lndet_LU_dstry(Gaudin_Quench)) - 0.5 * real(lndet_LU_dstry(Gaudin)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_ln_Overlap.cc
|
||||
|
||||
Purpose: Calculates Nikita Slavnov's determinant, case RHS is Bethe
|
||||
and LHS is arbitrary
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
/*
|
||||
complex<DP> Fn_V (int j, int sign, Vect<complex<DP> >& lstate_lambdaoc, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
complex<DP> result_num = 1.0;
|
||||
complex<DP> result_den = 1.0;
|
||||
|
||||
complex<DP> signcx = complex<DP>(sign);
|
||||
|
||||
for (int m = 0; m < rstate.N; ++m) {
|
||||
result_num *= (lstate_lambdaoc[m] - rstate.lambdaoc[j] + signcx * II);
|
||||
result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + signcx * II);
|
||||
}
|
||||
|
||||
return(result_num/result_den);
|
||||
}
|
||||
*/
|
||||
|
||||
complex<DP> LiebLin_ln_Overlap (Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
Vect<complex<DP> > lstate_lambdaoc_CX(rstate.N);
|
||||
for (int i = 0; i < rstate.N; ++i) lstate_lambdaoc_CX[i] = complex<DP>(lstate_lambdaoc[i]);
|
||||
return(LiebLin_ln_Overlap(lstate_lambdaoc_CX, lstate_lnnorm, rstate));
|
||||
}
|
||||
|
||||
complex<DP> LiebLin_ln_Overlap (Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
// Computes the log of the overlap between the left state and the Bethe rstate
|
||||
|
||||
// IMPORTANT ASSUMPTIONS:
|
||||
// The length over which the overlap is calculated is that in rstate
|
||||
|
||||
if (lstate_lambdaoc.size() != rstate.N) {
|
||||
cout << "Caution: calling overlap of states with difference charges. Are you sure that's what you want ?" << endl;
|
||||
return(0.0);
|
||||
}
|
||||
|
||||
// \mu are rstate rapidities, \lambda are from lstate (not BE)
|
||||
|
||||
Vect_CX ln_prod_plus(0.0, rstate.N); // contains \prod_a (\mu_a - lambdaoc_k + II)
|
||||
Vect_CX ln_prod_minus(0.0, rstate.N); // contains \prod_a (\mu_a - \lambdaoc_k - II)
|
||||
Vect_CX ln_prod_ll_plus (0.0, rstate.N); // contains \prod_{a \neq k} (\lambdaoc_a - \lambdaoc_k + II)
|
||||
Vect_CX ln_prod_ll_minus (0.0, rstate.N); // contains \prod_{a \neq k} (\lambdaoc_a - \lambdaoc_k - II)
|
||||
|
||||
for (int j = 0; j < rstate.N; ++j)
|
||||
for (int k = 0; k < rstate.N; ++k) {
|
||||
ln_prod_plus[k] += log(rstate.lambdaoc[j] - lstate_lambdaoc[k] + II);
|
||||
ln_prod_minus[k] += log(rstate.lambdaoc[j] - lstate_lambdaoc[k] - II);
|
||||
if (j != k) {
|
||||
ln_prod_ll_plus[k] += log(lstate_lambdaoc[j] - lstate_lambdaoc[k] + II);
|
||||
ln_prod_ll_minus[k] += log(lstate_lambdaoc[j] - lstate_lambdaoc[k] - II);
|
||||
}
|
||||
}
|
||||
|
||||
// Build the matrix:
|
||||
SQMat_CX Omega (0.0, rstate.N);
|
||||
|
||||
for (int j = 0; j < rstate.N; ++j)
|
||||
for (int k = 0; k < rstate.N; ++k)
|
||||
//Omega[j][k] = exp(-II * rstate.cxL * lstate_lambdaoc[k] + ln_prod_plus[k] - ln_prod_ll_plus[k])
|
||||
//* (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] + II)))
|
||||
//- (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] - II)))
|
||||
//* exp(ln_prod_minus[k] - ln_prod_ll_plus[k]);
|
||||
Omega[j][k] = exp(-II * rstate.cxL * lstate_lambdaoc[k] - ln_prod_plus[k] + ln_prod_minus[k])
|
||||
* (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] - II)))
|
||||
- (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] + II)));
|
||||
|
||||
|
||||
//for (int j = 0; j < rstate.N; ++j) {
|
||||
//for (int k = 0; k < rstate.N; ++k)
|
||||
//cout << Omega[j][k] << "\t";
|
||||
//cout << endl;
|
||||
//}
|
||||
|
||||
|
||||
complex<DP> lndetOmega = lndet_LU_CX_dstry(Omega);
|
||||
|
||||
//cout << "lndetOmega = " << lndetOmega << endl;
|
||||
|
||||
// Prefactors:
|
||||
complex<DP> ln_prod_d_mu = II * 0.5 * rstate.cxL * rstate.lambdaoc.sum();
|
||||
complex<DP> ln_prod_d_lambdaoc = II * 0.5 * rstate.cxL * lstate_lambdaoc.sum();
|
||||
|
||||
complex<DP> ln_prod_mu = 0.0;
|
||||
complex<DP> ln_prod_lambdaoc = 0.0;
|
||||
complex<DP> ln_prod_plusminus = 0.0;
|
||||
for (int j = 0; j < rstate.N - 1; ++j)
|
||||
for (int k = j+1; k < rstate.N; ++k) {
|
||||
ln_prod_mu += log(rstate.lambdaoc[k] - rstate.lambdaoc[j]);
|
||||
//ln_prod_lambdaoc += log((lstate_lambdaoc[j] - lstate_lambdaoc[k] + II) * (lstate_lambdaoc[j] - lstate_lambdaoc[k] - II)/(lstate_lambdaoc[k] - lstate_lambdaoc[j]));
|
||||
ln_prod_lambdaoc += log(lstate_lambdaoc[k] - lstate_lambdaoc[j]);
|
||||
}
|
||||
|
||||
for (int j = 0; j < rstate.N; ++j)
|
||||
for (int k = 0; k < rstate.N; ++k)
|
||||
ln_prod_plusminus += log((rstate.lambdaoc[j] - lstate_lambdaoc[k] + II));
|
||||
|
||||
//cout << "ln_prod_mu " << ln_prod_mu << "\tln_prod_lambdaoc " << ln_prod_lambdaoc << "\tln_prod_plusminus " << ln_prod_plusminus
|
||||
// << "\texp1 " << exp(-ln_prod_mu - ln_prod_lambdaoc) << "\texp2 " << exp(ln_prod_plusminus) << endl;
|
||||
|
||||
//if (real(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu + ln_prod_lambdaoc + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm)) > 10.0) {
|
||||
//cout << ln_prod_d_mu << "\t" << ln_prod_d_lambdaoc << "\t" << -ln_prod_mu << "\t" << ln_prod_lambdaoc << "\t" << lndetOmega << "\t" << -0.5 * lstate_lnnorm << "\t" << -0.5 * rstate.lnnorm << endl; cout << ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu + ln_prod_lambdaoc + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm) << endl;
|
||||
//JSCerror("Overlap exceeds 1.");
|
||||
//}
|
||||
|
||||
//return(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu + ln_prod_lambdaoc + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
return(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu - ln_prod_lambdaoc + ln_prod_plusminus + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
}
|
||||
|
||||
/*
|
||||
// Incorrect version
|
||||
complex<DP> LiebLin_ln_Overlap (Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
// Computes the log of the overlap between the left state and the Bethe rstate
|
||||
|
||||
// If momentum difference is zero but states are different, then form factor is zero:
|
||||
|
||||
SQMat_CX one_plus_U (0.0, rstate.N);
|
||||
|
||||
Vect_CX Vplus (0.0, rstate.N); // contains V^+_j
|
||||
Vect_CX Vminus (0.0, rstate.N); // contains V^-_j
|
||||
Vect_CX Fn_Prod (0.0, rstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
|
||||
//Vect_DP rKern (0.0, rstate.N); // K(lambdaoc_j - lambdaoc_p)
|
||||
|
||||
//int p = 0;
|
||||
|
||||
complex<DP> Kout = lstate_lambdaoc.sum() - rstate.K;
|
||||
|
||||
for (int a = 0; a < rstate.N; ++a) {
|
||||
Vplus[a] = Fn_V (a, 1, lstate_lambdaoc, rstate);
|
||||
Vminus[a] = Fn_V (a, -1, lstate_lambdaoc, rstate);
|
||||
Fn_Prod[a] = 1.0;
|
||||
for (int m = 0; m < rstate.N; ++m)
|
||||
if (m != a) Fn_Prod[a] *= (lstate_lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
|
||||
//rKern[a] = rstate.Kernel (a, p);
|
||||
}
|
||||
|
||||
for (int a = 0; a < rstate.N; ++a)
|
||||
for (int b = 0; b < rstate.N; ++b)
|
||||
one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + II * ((lstate_lambdaoc[a] - rstate.lambdaoc[a])/(Vplus[a] - Vminus[a]))
|
||||
* Fn_Prod[a] * rstate.Kernel(a,b);
|
||||
|
||||
complex<DP> ln_ddalpha_sigma = lndet_LU_CX_dstry(one_plus_U);
|
||||
|
||||
complex<DP> ln_prod_V = 0.0;
|
||||
for (int a = 0; a < rstate.N; ++a) ln_prod_V += log(Vplus[a] - Vminus[a]);
|
||||
|
||||
complex<DP> ln_prod_2 = 0.0;
|
||||
for (int a = 0; a < rstate.N; ++a)
|
||||
for (int b = 0; b < rstate.N; ++b)
|
||||
ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate_lambdaoc[a] - rstate.lambdaoc[b]));
|
||||
|
||||
//cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << endl;
|
||||
cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << 0.5 * lstate_lnnorm << "\t" << 0.5 * rstate.lnnorm << endl;//- log(Vplus[p] - Vminus[p]) << endl;
|
||||
|
||||
ln_ddalpha_sigma += ln_prod_V + ln_prod_2;// - log(Vplus[p] - Vminus[p]);
|
||||
|
||||
//cout << "shift = " << (complex<DP>(rstate.N) * (lstate_lambdaoc[0] - rstate.lambdaoc[0])/twoPI) << "\tKout = " << Kout << "\texp(-II*Kout) = " << exp(-II * Kout)
|
||||
// << "\tlog(exp(-II * Kout) - 1.0) = " << log(exp(-II * Kout) - 1.0) << endl;
|
||||
//cout << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(Vplus[p] - Vminus[p]) << "\t" << lstate_lnnorm << endl << endl;
|
||||
|
||||
return (ln_ddalpha_sigma - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
}
|
||||
*/
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,97 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: ln_Density_ME.cc
|
||||
|
||||
Purpose: Computes the density operator \rho(x = 0) matrix element
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
complex<DP> Fn_V (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
//complex<DP> result_num = 1.0;
|
||||
//complex<DP> result_den = 1.0;
|
||||
complex<DP> result = 1.0;
|
||||
|
||||
for (int m = 0; m < lstate.N; ++m) {
|
||||
//result_num *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
//result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
result *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II)/(rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
}
|
||||
|
||||
//return(result_num/result_den);
|
||||
return(result);
|
||||
}
|
||||
|
||||
complex<DP> ln_Density_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
// Computes the log of the density operator \rho(x = 0) matrix element between lstate and rstate.
|
||||
|
||||
// If we have lstate == rstate, density matrix element = N/L:
|
||||
|
||||
if (lstate.Ix2 == rstate.Ix2) return(log(lstate.N/lstate.L));
|
||||
|
||||
// If momentum difference is zero but states are different, then matrix element is zero:
|
||||
|
||||
else if (lstate.iK == rstate.iK) return(-200.0); // so exp(.) is zero
|
||||
|
||||
SQMat_DP one_plus_U (0.0, lstate.N);
|
||||
|
||||
Vect_CX Vplus (0.0, lstate.N); // contains V^+_j; V^-_j is the conjugate
|
||||
//Vect_DP Fn_Prod (0.0, lstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
|
||||
// From ABACUS++G_3 onwards: use logs to stabilize numerical values at small c, at the cost of execution speed.
|
||||
Vect_CX ln_Fn_Prod (0.0, lstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
|
||||
Vect_DP rKern (0.0, lstate.N); // K(lambdaoc_j - lambdaoc_(p == arbitrary))
|
||||
|
||||
//int p = 0;
|
||||
int p = rstate.N/2-1; // choice doesn't matter, see 1990_Slavnov_TMP_82 after (3.8). Choose rapidity around the middle.
|
||||
|
||||
DP Kout = lstate.K - rstate.K;
|
||||
|
||||
for (int a = 0; a < lstate.N; ++a) {
|
||||
Vplus[a] = Fn_V (a, lstate, rstate);
|
||||
//Fn_Prod[a] = 1.0;
|
||||
ln_Fn_Prod[a] = 0.0;;
|
||||
for (int m = 0; m < lstate.N; ++m)
|
||||
//if (m != a) Fn_Prod[a] *= (lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
|
||||
if (m != a) ln_Fn_Prod[a] += log(complex<DP>(lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]));
|
||||
rKern[a] = rstate.Kernel (a, p);
|
||||
}
|
||||
|
||||
for (int a = 0; a < lstate.N; ++a)
|
||||
for (int b = 0; b < lstate.N; ++b)
|
||||
one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + 0.5 * ((lstate.lambdaoc[a] - rstate.lambdaoc[a])/imag(Vplus[a]))
|
||||
//* Fn_Prod[a] * (rstate.Kernel(a,b) - rKern[b]);
|
||||
* real(exp(ln_Fn_Prod[a])) * (rstate.Kernel(a,b) - rKern[b]);
|
||||
|
||||
complex<DP> ln_ddalpha_sigma = lndet_LU_dstry(one_plus_U);
|
||||
|
||||
complex<DP> ln_prod_V = 0.0;
|
||||
for (int a = 0; a < lstate.N; ++a) ln_prod_V += log(2.0 * II * imag(Vplus[a]));
|
||||
|
||||
complex<DP> ln_prod_2 = 0.0;
|
||||
for (int a = 0; a < lstate.N; ++a)
|
||||
for (int b = 0; b < lstate.N; ++b)
|
||||
ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate.lambdaoc[a] - rstate.lambdaoc[b]));
|
||||
|
||||
//cout << "ln_Fn_Prod = " << ln_Fn_Prod << endl;
|
||||
//cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << "\t" << - 0.5 * (lstate.lnnorm + rstate.lnnorm) << "\t" << ln_ddalpha_sigma + ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p])) - 0.5 * (lstate.lnnorm + rstate.lnnorm) << endl;
|
||||
|
||||
ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p]));
|
||||
|
||||
return (log(-II * Kout) + ln_ddalpha_sigma - 0.5 * (lstate.lnnorm + rstate.lnnorm));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: ln_Psi_ME.cc
|
||||
|
||||
Purpose: Computes the matrix element of \Psi (x = 0)
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
complex<DP> Fn_V_Psi (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
// lstate has one particle less than rstate
|
||||
|
||||
complex<DP> result_num = 1.0;
|
||||
complex<DP> result_den = 1.0;
|
||||
|
||||
for (int m = 0; m < lstate.N; ++m)
|
||||
result_num *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
|
||||
for (int m = 0; m < rstate.N; ++m)
|
||||
result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
|
||||
return(result_num/result_den);
|
||||
}
|
||||
|
||||
complex<DP> ln_Psi_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
// Computes the log of the annihilation operator matrix element between lstate and rstate.
|
||||
|
||||
if (lstate.N + 1 != rstate.N) JSCerror("Wrong particle numbers in left and right states for Psi FF.");
|
||||
|
||||
SQMat_DP U_Psi (0.0, lstate.N);
|
||||
|
||||
Vect_CX Vplus (0.0, lstate.N); // contains V^+_j; V^-_j is the conjugate
|
||||
Vect_DP Fn_Prod (0.0, lstate.N); // product_{m} (\mu_m - \lambdaoc_j)/product_{m neq j} (\lambdaoc_m - \lambdaoc_j)
|
||||
Vect_DP rKern (0.0, lstate.N); // K(lambdaoc_j - lambdaoc_(p == N))
|
||||
|
||||
int p = rstate.N - 1;
|
||||
|
||||
for (int a = 0; a < lstate.N; ++a) {
|
||||
Vplus[a] = Fn_V_Psi (a, lstate, rstate);
|
||||
Fn_Prod[a] = (lstate.lambdaoc[a] - rstate.lambdaoc[a])/(rstate.lambdaoc[rstate.N - 1] - rstate.lambdaoc[a]);
|
||||
for (int m = 0; m < lstate.N; ++m)
|
||||
if (m != a) Fn_Prod[a] *= (lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
|
||||
rKern[a] = rstate.Kernel (a, p);
|
||||
}
|
||||
|
||||
for (int a = 0; a < lstate.N; ++a)
|
||||
for (int b = 0; b < lstate.N; ++b)
|
||||
U_Psi[a][b] = (a == b ? 2.0 * imag(Vplus[a]) : 0.0) + Fn_Prod[a] * (rstate.Kernel(a,b) - rKern[b]);
|
||||
|
||||
complex<DP> ln_det_U_Psi = lndet_LU_dstry(U_Psi);
|
||||
|
||||
complex<DP> ln_prod_lambdaocsq_plus_one = 0.0;
|
||||
for (int a = 0; a < rstate.N - 1; ++a)
|
||||
for (int b = a; b < rstate.N; ++b)
|
||||
ln_prod_lambdaocsq_plus_one += log(complex<DP>((rstate.lambdaoc[a] - rstate.lambdaoc[b]) * (rstate.lambdaoc[a] - rstate.lambdaoc[b])) + 1.0);
|
||||
|
||||
complex<DP> ln_prod_lambdaoca_min_mub = 0.0;
|
||||
for (int a = 0; a < rstate.N; ++a)
|
||||
for (int b = 0; b < lstate.N; ++b)
|
||||
ln_prod_lambdaoca_min_mub += log(complex<DP>(rstate.lambdaoc[a] - lstate.lambdaoc[b]));
|
||||
|
||||
//cout << endl << "Factors are " << ln_det_U_Psi << "\t" << ln_prod_lambdaocsq_plus_one << "\t" << ln_prod_lambdaoca_min_mub << endl;
|
||||
|
||||
return (ln_det_U_Psi + 0.5 * log(lstate.c_int) + ln_prod_lambdaocsq_plus_one - ln_prod_lambdaoca_min_mub - 0.5 * (lstate.lnnorm + rstate.lnnorm));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/LIEBLIN/ln_g2_ME.cc
|
||||
|
||||
Purpose: provides the matrix element of the second density moment g2(x = 0)
|
||||
|
||||
NOTE: based on Lorenzo Piroli's expression of the matrix element
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
/*
|
||||
complex<DP> ln_g2_ME_old_jacopo (LiebLin_Bethe_State& mu, LiebLin_Bethe_State& lambda)
|
||||
{
|
||||
|
||||
if (mu.Ix2 == lambda.Ix2) return(-200.);
|
||||
|
||||
DP c_int = mu.c_int;
|
||||
|
||||
SQMat_CX G(lambda.N);
|
||||
SQMat_CX GpB(lambda.N);
|
||||
SQMat_CX B(lambda.N);
|
||||
|
||||
complex<DP> log_themp;
|
||||
complex<DP> lnprefactor = 0. ;
|
||||
|
||||
lnprefactor += 2.*log(c_int) ;
|
||||
|
||||
for(int j=0; j < mu.N; ++j){
|
||||
for(int k=0; k < j; ++k){
|
||||
lnprefactor -= log((mu.lambdaoc[j] - mu.lambdaoc[k]));
|
||||
lnprefactor -= log((lambda.lambdaoc[j] - lambda.lambdaoc[k]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(int j=0; j < mu.N; ++j){
|
||||
for(int k=0; k <mu.N; ++k){
|
||||
lnprefactor += log(mu.lambdaoc[j] - mu.lambdaoc[k] + II);
|
||||
}
|
||||
}
|
||||
|
||||
Vect_CX VVP (0.0, mu.N);
|
||||
Vect_CX VVM (0.0, mu.N);
|
||||
|
||||
//compute the vectors
|
||||
for(int j=0; j < mu.N; ++j) {
|
||||
log_themp = 0.;
|
||||
for(int k=0; k < mu.N; ++k) log_themp += log(mu.lambdaoc[j] - lambda.lambdaoc[k] + II) - log(mu.lambdaoc[j] - mu.lambdaoc[k] + II);
|
||||
VVP[j] = exp(log_themp);
|
||||
}
|
||||
|
||||
for(int j=0; j < mu.N; ++j) {
|
||||
log_themp = 0.;
|
||||
for(int k=0; k < mu.N; ++k) log_themp += log(mu.lambdaoc[j] - lambda.lambdaoc[k] - II) - log(mu.lambdaoc[j] - mu.lambdaoc[k] - II);
|
||||
VVM[j] = exp(log_themp);
|
||||
}
|
||||
|
||||
//compute the sum of determinants
|
||||
complex<DP> sum_n =0.;
|
||||
for(int n=0; n < mu.N; ++n) {
|
||||
// compute the matrices
|
||||
for (int a = 0; a < mu.N; ++a){
|
||||
for (int b = 0; b < mu.N; ++b){
|
||||
if(b == n){
|
||||
G[a][b] = 2.*II* lambda.lambdaoc[a];
|
||||
}
|
||||
else{
|
||||
G[a][b] = II*1./(lambda.lambdaoc[a] - mu.lambdaoc[b])*( VVP[b]*1.0/(mu.lambdaoc[b] - lambda.lambdaoc[a] + II) +
|
||||
VVM[b]*1.0/(mu.lambdaoc[b] - lambda.lambdaoc[a] - II) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 0; a < mu.N; ++a){
|
||||
for (int b = 0; b < mu.N; ++b){
|
||||
if(b == n){
|
||||
B[a][b] = 0.;
|
||||
}
|
||||
else{
|
||||
B[a][b] = II*1.0/(mu.lambdaoc[b] - mu.lambdaoc[n] - II) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 0; a < mu.N; ++a){
|
||||
for (int b = 0; b < mu.N; ++b){
|
||||
GpB[a][b] = G[a][b] + B[a][b];
|
||||
}
|
||||
}
|
||||
//finally add
|
||||
sum_n += exp( lndet_LU_CX(GpB) ) - exp(lndet_LU_CX(G) ) ;
|
||||
}
|
||||
|
||||
return(log(sum_n ) + lnprefactor - 0.5 * (mu.lnnorm + lambda.lnnorm));
|
||||
}
|
||||
*/
|
||||
complex<DP> Fn_V_g2 (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
//complex<DP> result_num = 1.0;
|
||||
//complex<DP> result_den = 1.0;
|
||||
complex<DP> result = 1.0;
|
||||
|
||||
for (int m = 0; m < lstate.N; ++m) {
|
||||
//result_num *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
//result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
result *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II)/(rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
}
|
||||
|
||||
//return(result_num/result_den);
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
complex<DP> ln_g2_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
// Computes the log of the density operator \rho(x = 0) matrix element between lstate and rstate.
|
||||
|
||||
// If we have lstate == rstate, density matrix element = 0:
|
||||
|
||||
|
||||
if (lstate.Ix2 == rstate.Ix2) return(-200.);
|
||||
|
||||
|
||||
|
||||
|
||||
SQMat_DP one_plus_U (0.0, lstate.N);
|
||||
|
||||
Vect_CX Vplus (0.0, lstate.N); // contains V^+_j; V^-_j is the conjugate
|
||||
//Vect_DP Fn_Prod (0.0, lstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
|
||||
// From ABACUS++G_3 onwards: use logs to stabilize numerical values at small c, at the cost of execution speed.
|
||||
Vect_CX ln_Fn_Prod (0.0, lstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
|
||||
Vect_DP rKern (0.0, lstate.N); // K(lambdaoc_j - lambdaoc_(p == arbitrary))
|
||||
|
||||
//int p = 0;
|
||||
int p = rstate.N/2-1; // choice doesn't matter, see 1990_Slavnov_TMP_82 after (3.8). Choose rapidity around the middle.
|
||||
|
||||
|
||||
DP c_int = rstate.c_int;
|
||||
|
||||
DP Eout = log(pow(lstate.E - rstate.E,2.)) - (2)*log(c_int) - log(2*lstate.N);
|
||||
|
||||
for (int a = 0; a < lstate.N; ++a) {
|
||||
Vplus[a] = Fn_V_g2 (a, lstate, rstate);
|
||||
//Fn_Prod[a] = 1.0;
|
||||
ln_Fn_Prod[a] = 0.0;;
|
||||
for (int m = 0; m < lstate.N; ++m)
|
||||
//if (m != a) Fn_Prod[a] *= (lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
|
||||
if (m != a) ln_Fn_Prod[a] += log(complex<DP>(lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]));
|
||||
rKern[a] = rstate.Kernel (a, p);
|
||||
}
|
||||
|
||||
for (int a = 0; a < lstate.N; ++a)
|
||||
for (int b = 0; b < lstate.N; ++b)
|
||||
one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + 0.5 * 1./imag(Vplus[a])
|
||||
//* Fn_Prod[a] * (rstate.Kernel(a,b) - rKern[b]);
|
||||
* ((lstate.lambdaoc[a] - rstate.lambdaoc[a])*real(exp(ln_Fn_Prod[a])) * (rstate.Kernel(a,b) - rKern[b]) + rKern[b]);
|
||||
|
||||
complex<DP> ln_ddalpha_sigma = lndet_LU_dstry(one_plus_U);
|
||||
|
||||
complex<DP> ln_prod_V = 0.0;
|
||||
for (int a = 0; a < lstate.N; ++a) ln_prod_V += log(2.0 * II * imag(Vplus[a]));
|
||||
|
||||
complex<DP> ln_prod_2 = 0.0;
|
||||
for (int a = 0; a < lstate.N; ++a)
|
||||
for (int b = 0; b < lstate.N; ++b)
|
||||
ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate.lambdaoc[a] - rstate.lambdaoc[b]));
|
||||
|
||||
//cout << "ln_Fn_Prod = " << ln_Fn_Prod << endl;
|
||||
//cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << "\t" << - 0.5 * (lstate.lnnorm + rstate.lnnorm) << "\t" << ln_ddalpha_sigma + ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p])) - 0.5 * (lstate.lnnorm + rstate.lnnorm) << endl;
|
||||
|
||||
ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p]));
|
||||
|
||||
return (log(II) + Eout + ln_ddalpha_sigma - 0.5 * (lstate.lnnorm + rstate.lnnorm));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace JSC
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "JSC.h"
|
||||
using namespace std;
|
||||
|
||||
void JSC::balanc(SQMat_DP& a)
|
||||
{
|
||||
// Balancing of nonsymmetric matrix. See NR p.489.
|
||||
|
||||
const DP RADIX = numeric_limits<DP>::radix;
|
||||
|
||||
int i, j, last = 0;
|
||||
DP s, r, g, f, c, sqrdx;
|
||||
|
||||
int n = a.size();
|
||||
sqrdx = RADIX * RADIX;
|
||||
|
||||
while (last == 0) {
|
||||
last = 1;
|
||||
for (i = 0; i < n; i++) {
|
||||
r = c = 0.0;
|
||||
for (j = 0; j < n; j++)
|
||||
if (j != i) {
|
||||
c += fabs(a[j][i]);
|
||||
r += fabs(a[i][j]);
|
||||
}
|
||||
if (c != 0.0 && r != 0.0) {
|
||||
g = r/RADIX;
|
||||
f = 1.0;
|
||||
s = c + r;
|
||||
while (c < g) {
|
||||
f *= RADIX;
|
||||
c *= sqrdx;
|
||||
}
|
||||
g = r * RADIX;
|
||||
while (c > g) {
|
||||
f /= RADIX;
|
||||
c /= sqrdx;
|
||||
}
|
||||
if ((c + r)/f < 0.95 * s) {
|
||||
last = 0;
|
||||
g = 1.0/f;
|
||||
for (j = 0; j < n; j++) a[i][j] *= g;
|
||||
for (j = 0; j < n; j++) a[j][i] *= f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "JSC.h"
|
||||
using namespace std;
|
||||
|
||||
DP JSC::det_LU (SQMat_DP a)
|
||||
{
|
||||
// Returns the determinant of matrix a, through LU decomposition
|
||||
// In order to preserve the original matrix, it is copied first.
|
||||
|
||||
Vect_INT indx(a.size());
|
||||
|
||||
SQMat_DP mat = a;
|
||||
|
||||
DP d;
|
||||
|
||||
JSC::ludcmp (mat, indx, d);
|
||||
|
||||
for (int j = 0; j < mat.size(); j++) d *= mat[j][j];
|
||||
|
||||
return(d);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "JSC.h"
|
||||
using namespace std;
|
||||
|
||||
complex<DP> JSC::det_LU_CX (SQMat_CX a)
|
||||
{
|
||||
// Returns the determinant of matrix a, through LU decomposition
|
||||
|
||||
Vect_INT indx(a.size());
|
||||
|
||||
SQMat_CX mat = a;
|
||||
|
||||
DP d;
|
||||
|
||||
JSC::ludcmp_CX (mat, indx, d);
|
||||
|
||||
complex<DP> dd = d;
|
||||
|
||||
for (int j = 0; j < mat.size(); j++) dd *= mat[j][j];
|
||||
|
||||
return(dd);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "JSC.h"
|
||||
|
||||
void JSC::eigsrt (Vect_DP& d, SQMat_DP& v)
|
||||
{
|
||||
// This puts the eigenvalues in INCREASING order, not decreasing as in NR !
|
||||
|
||||
int i, j, k;
|
||||
DP p;
|
||||
|
||||
int n = d.size();
|
||||
for (i = 0; i < n-1; i++) {
|
||||
p = d[k=i];
|
||||
for (j = i; j < n; j++) {
|
||||
if (d[j] <= p) {
|
||||
p = d[k = j];
|
||||
}
|
||||
}
|
||||
if (k != i) {
|
||||
d[k] = d[i];
|
||||
d[i] = p;
|
||||
for (j = 0; j < n; j++) {
|
||||
p = v[j][i];
|
||||
v[j][i] = v[j][k];
|
||||
v[j][k] = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "JSC.h"
|
||||
using namespace std;
|
||||
|
||||
void JSC::elmhes(SQMat_DP& a)
|
||||
{
|
||||
// Reduction to Hessenberg form by elimination method. NR p.490
|
||||
|
||||
int i, j, m;
|
||||
DP y, x;
|
||||
|
||||
int n = a.size();
|
||||
for (m = 1; m < n-1; m++) {
|
||||
x = 0.0;
|
||||
i = m;
|
||||
for (j = m; j < n; j++) {
|
||||
if (fabs(a[j][m-1]) > fabs(x)) {
|
||||
x = a[j][m-1];
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
if (i != m) {
|
||||
for (j = m - 1; j < n; j++) SWAP(a[i][j], a[m][j]);
|
||||
for (j = 0; j < n; j++) SWAP(a[j][i], a[j][m]);
|
||||
}
|
||||
if (x != 0.0) {
|
||||
for (i = m + 1; i < n; i++) {
|
||||
if ((y = a[i][m-1]) != 0.0) {
|
||||
y /= x;
|
||||
a[i][m-1] = y;
|
||||
for (j = m; j < n; j++) a[i][j] -= y*a[m][j];
|
||||
for (j = 0; j < n; j++) a[j][m] += y*a[j][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#include "JSC.h"
|
||||
using namespace std;
|
||||
|
||||
void JSC::gaussj (SQMat_DP& a, SQMat_DP& b)
|
||||
{
|
||||
int i, j, k, l, ll;
|
||||
int icol = 0;
|
||||
int irow = 0;
|
||||
DP big, dum, pivinv;
|
||||
|
||||
int n = a.size();
|
||||
int m = b.size();
|
||||
Vect_INT indxc(n), indxr(n), ipiv(n);
|
||||
for (j = 0; j < n; j++) ipiv[j] = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
big = 0.0;
|
||||
for (j = 0; j < n; j++)
|
||||
if (ipiv[j] != 1)
|
||||
for (k = 0; k < n; k++) {
|
||||
if (ipiv[k] == 0) {
|
||||
if (fabs(a[j][k]) >= big) {
|
||||
big = fabs(a[j][k]);
|
||||
irow = j;
|
||||
icol = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
++(ipiv[icol]);
|
||||
|
||||
if (irow != icol) {
|
||||
for (l = 0; l < n; l++) SWAP (a[irow][l], a[icol][l]);
|
||||
for (l = 0; l < m; l++) SWAP (b[irow][l], b[icol][l]);
|
||||
}
|
||||
indxr[i] = irow;
|
||||
indxc[i] = icol;
|
||||
if (a[icol][icol] == 0.0) JSCerror("gaussj: singular matrix");
|
||||
pivinv = 1.0/a[icol][icol];
|
||||
a[icol][icol] = 1.0;
|
||||
for (l = 0; l < n; l++) a[icol][l] *= pivinv;
|
||||
for (l = 0; l < m; l++) b[icol][l] *= pivinv;
|
||||
for (ll = 0; ll < n; ll++)
|
||||
if (ll != icol) {
|
||||
dum = a[ll][icol];
|
||||
a[ll][icol] = 0.0;
|
||||
for (l = 0; l < n; l++) a[ll][l] -= a[icol][l] * dum;
|
||||
for (l = 0; l < m; l++) b[ll][l] -= b[icol][l] * dum;
|
||||
}
|
||||
}
|
||||
|
||||
for (l = n - 1; l >= 0; l--) {
|
||||
if (indxr[l] != indxc[l])
|
||||
for (k = 0; k < n; k++)
|
||||
SWAP (a[k][indxr[l]], a[k][indxc[l]]);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user