Cleanup of source files: first pass, up to src/INTEG

This commit is contained in:
J.-S. Caux 2018-02-10 21:25:24 +01:00
parent 63cdd4250c
commit d337885305
75 changed files with 2970 additions and 4588 deletions

View File

@ -30,7 +30,8 @@ namespace ABACUS {
Base::Base (const Base& RefBase) // copy constructor Base::Base (const Base& RefBase) // copy constructor
: Charge(RefBase.Charge), Nrap(Vect<int>(RefBase.Nrap.size())), Nraptot(RefBase.Nraptot), : 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) 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) { for (int i = 0; i < Nrap.size(); ++i) {
Nrap[i] = RefBase.Nrap[i]; Nrap[i] = RefBase.Nrap[i];
@ -39,36 +40,14 @@ namespace ABACUS {
} }
} }
/*
// 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) 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)), : Charge(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)),
Ix2_max(Vect<int>(RefChain.Nstrings)),
id (0LL) id (0LL)
{ {
// Check consistency of Nrapidities vector with RefChain // Check consistency of Nrapidities vector with RefChain
if (RefChain.Nstrings != Nrapidities.size())
//if (RefChain.Nstrings != Nrapidities.size()) cout << "error: Nstrings = " << RefChain.Nstrings << "\tNrap.size = " << Nrapidities.size() << endl; ABACUSerror("Incompatible Nrapidities vector used in Base constructor.");
if (RefChain.Nstrings != Nrapidities.size()) ABACUSerror("Incompatible Nrapidities vector used in Base constructor.");
int Mcheck = 0; int Mcheck = 0;
for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i]; for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
@ -86,13 +65,12 @@ namespace ABACUS {
} }
// Now compute the Ix2_infty numbers // Now compute the Ix2_infty numbers
(*this).Compute_Ix2_limits(RefChain); (*this).Compute_Ix2_limits(RefChain);
} }
Base::Base (const Heis_Chain& RefChain, long long int id_ref) 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)), : Charge(0), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0),
Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)),
id (id_ref) id (id_ref)
{ {
// Build Nrapidities vector from id_ref // Build Nrapidities vector from id_ref
@ -106,14 +84,6 @@ namespace ABACUS {
} }
Nrap[0] = id_eff; 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()) ABACUSerror("Incompatible Nrapidities vector used in Base constructor.");
int Mcheck = 0; int Mcheck = 0;
for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i]; for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
Charge = Mcheck; Charge = Mcheck;
@ -122,7 +92,6 @@ namespace ABACUS {
for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i]; for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
// Now compute the Ix2_infty numbers // Now compute the Ix2_infty numbers
(*this).Compute_Ix2_limits(RefChain); (*this).Compute_Ix2_limits(RefChain);
} }
@ -172,20 +141,23 @@ namespace ABACUS {
sum2 = 0.0; 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]) sum2 += (RefChain.Str_L[j] == RefChain.Str_L[k]) ? 0.0 :
- 0.5 * fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) * RefChain.anis)); 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]) 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)); - 0.5 * (RefChain.Str_L[j] + RefChain.Str_L[k]) * RefChain.anis));
for (int a = 1; a < ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]); ++a) for (int a = 1; a < ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]); ++a)
sum2 += 2.0 * 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k]) 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)); - 0.5 * (fabs(RefChain.Str_L[j] - RefChain.Str_L[k])
+ 2.0*a) * RefChain.anis));
sum1 += (Nrap[k] - ((j == k) ? 1 : 0)) * sum2; 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]) Ix2_infty[j] = (1.0/PI) * fabs(RefChain.Nsites *
- 0.5 * RefChain.Str_L[j] * RefChain.anis)) - sum1); 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. } // The Ix2_infty are now set.
@ -293,9 +265,6 @@ namespace ABACUS {
Ix2_max[j] -= 2; Ix2_max[j] -= 2;
} }
// Fudge, for strings:
//if (RefChain.Str_L[j] >= 1) Ix2_max[j] += 2;
//Ix2_max[j] += 2;
} }
} // if XXZ_gpd } // if XXZ_gpd
@ -303,6 +272,4 @@ namespace ABACUS {
} }
} // namespace ABACUS } // namespace ABACUS

View File

@ -22,7 +22,8 @@ using namespace std;
namespace ABACUS { namespace ABACUS {
Bethe_State::Bethe_State (long long int base_id_ref, long long int type_id_ref, long long int id_ref, long long int maxid_ref) : 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) {} base_id(base_id_ref), type_id(type_id_ref), id(id_ref), maxid(maxid_ref) {}
} // namespace ABACUS } // namespace ABACUS

View File

@ -10,6 +10,8 @@ File: src/BETHE/Offsets.cc
Purpose: defines functions in Offsets class. Purpose: defines functions in Offsets class.
IN DEVELOPMENT
***********************************************************/ ***********************************************************/
#include "ABACUS.h" #include "ABACUS.h"

View File

@ -8,7 +8,7 @@ Copyright (c) J.-S. Caux.
Combinatorics.cc Combinatorics.cc
Defines all class related to combinatorics. Defines all classes related to combinatorics.
******************************************************************/ ******************************************************************/
@ -67,16 +67,16 @@ namespace ABACUS {
} }
std::ostream& operator<< (std::ostream& s, Choose_Table& Ref_table) 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;
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);
} }
s << endl;
return(s);
}
Choose_Table::~Choose_Table() Choose_Table::~Choose_Table()
{ {

View File

@ -20,7 +20,9 @@ using namespace ABACUS;
int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
if (argc != 7) ABACUSerror("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)."); if (argc != 7) ABACUSerror("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 c_int = atof(argv[1]);
DP mu = atof(argv[2]); DP mu = atof(argv[2]);
@ -30,12 +32,11 @@ int main(int argc, const char* argv[])
bool Save_data = bool(atoi(argv[6])); bool Save_data = bool(atoi(argv[6]));
if (c_int <= 0.0) ABACUSerror("Give a strictly positive c."); if (c_int <= 0.0) ABACUSerror("Give a strictly positive c.");
if (Omega <= 0.0) ABACUSerror("Give a strictly positive Omega, otherwise the algorithm cannot converge."); if (Omega <= 0.0) ABACUSerror("Give a strictly positive Omega, "
"otherwise the algorithm cannot converge.");
if (kBT <= 0.0) ABACUSerror("Negative T ? You must be a string theorist."); if (kBT <= 0.0) ABACUSerror("Negative T ? You must be a string theorist.");
if (Max_Secs < 10) ABACUSerror("Give more time."); if (Max_Secs < 10) ABACUSerror("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); Solve_2CBG_TBAE_via_refinements (c_int, mu, Omega, kBT, Max_Secs, Save_data);
return(0); return(0);

View File

@ -39,7 +39,6 @@ int main(int argc, char* argv[])
DP omega; DP omega;
int iK; int iK;
DP FF; DP FF;
//int conv;
DP dev; DP dev;
string label; string label;
@ -77,8 +76,11 @@ int main(int argc, char* argv[])
cout << "Entropy: \t" << -(sumFFsqlnFFsq - sumFFsq * log(sumFFsq))/sumFFsq << endl; cout << "Entropy: \t" << -(sumFFsqlnFFsq - sumFFsq * log(sumFFsq))/sumFFsq << endl;
cout << "iK\tnFFatK\tIPRatiK\tentropyatiK:" << 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; 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); return(0);
} }

View File

@ -24,7 +24,8 @@ int main(int argc, char* argv[])
if (argc != 7) { // print out some instructions if (argc != 7) { // print out some instructions
cout << "Usage of Check_RAW_File executable: provide the following arguments:" << endl; 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 << "(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; cout << "Check option: 0 == check for missing states, "
"1 == check for multiply-appearing states." << endl;
} }
char* rawfilename = argv[1]; char* rawfilename = argv[1];
@ -34,113 +35,102 @@ int main(int argc, char* argv[])
DP FFmin = atof(argv[5]); DP FFmin = atof(argv[5]);
int check_option = atoi(argv[6]); int check_option = atoi(argv[6]);
ifstream RAW_infile; ifstream RAW_infile;
RAW_infile.open(rawfilename); RAW_infile.open(rawfilename);
if (RAW_infile.fail()) { if (RAW_infile.fail()) {
cout << rawfilename << endl; cout << rawfilename << endl;
ABACUSerror("Could not open sorted RAW_infile... "); ABACUSerror("Could not open sorted RAW_infile... ");
} }
DP omega_next, omega, omega_prev; DP omega_next, omega, omega_prev;
int iK_next, iK, iK_prev; int iK_next, iK, iK_prev;
DP FF_next, FF, FF_prev; DP FF_next, FF, FF_prev;
//int conv_next, conv, conv_prev; DP dev_next, dev, dev_prev;
DP dev_next, dev, dev_prev; string label_next, label, label_prev;
string label_next, label, label_prev;
if (check_option > 1) { if (check_option > 1) {
FF = 0.0; FF = 0.0;
FF_prev = 0.0; FF_prev = 0.0;
FF_next = 0.0; FF_next = 0.0;
FFmin = -1.0; FFmin = -1.0;
} }
//RAW_infile >> omega >> iK >> FF >> conv >> label; RAW_infile >> omega >> iK;
RAW_infile >> omega >> iK; if (check_option <= 1) RAW_infile >> FF;
if (check_option <= 1) RAW_infile >> FF; RAW_infile >> dev;
RAW_infile >> dev; RAW_infile >> label;
RAW_infile >> label; RAW_infile >> omega_next >> iK_next;
//RAW_infile >> omega_next >> iK_next >> FF_next >> conv_next >> label_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; dev_prev = dev; label_prev = label;
omega = omega_next; iK = iK_next; FF = FF_next; dev = dev_next; label = label_next;
RAW_infile >> omega_next >> iK_next; RAW_infile >> omega_next >> iK_next;
if (check_option <= 1) RAW_infile >> FF_next; if (check_option <= 1) RAW_infile >> FF_next; // for non-Z checks
RAW_infile >> dev_next; RAW_infile >> dev_next;
RAW_infile >> label_next; RAW_infile >> label_next;
line++;
int line = 1; if (label.compare(label_next) == 0)
cout << "Identical labels around line " << line << ": " << endl
<< omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl;
char a; 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" << dev_prev << "\t" << label_prev << endl
<< omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl
<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << dev_next << "\t" << label_next << endl;
while (fabs(FF) > FFmin && RAW_infile.peek() != EOF) { cin >> a;
//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); 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" << dev_prev << "\t" << label_prev << endl
<< omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << 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;
}
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);
} }

View File

@ -26,11 +26,12 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Heis_DSF executable: " << endl; cout << endl << "Usage of Heis_DSF executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 << "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 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 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 << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << 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 << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
@ -44,8 +45,6 @@ int main(int argc, char* argv[])
DP Delta = atof(argv[ctr++]); DP Delta = atof(argv[ctr++]);
int N = atoi(argv[ctr++]); int N = atoi(argv[ctr++]);
int M = atoi(argv[ctr++]); int M = atoi(argv[ctr++]);
//int iKmin = atoi(argv[5]);
//int iKmax = atoi(argv[6]);
int Max_Secs = atoi(argv[ctr++]); int Max_Secs = atoi(argv[ctr++]);
DP target_sumrule = atof(argv[ctr++]); DP target_sumrule = atof(argv[ctr++]);
bool refine = (atoi(argv[ctr++]) == 1); bool refine = (atoi(argv[ctr++]) == 1);
@ -53,89 +52,8 @@ int main(int argc, char* argv[])
// We systematically scan over all momentum integers (to avoid problems with Brillouin folding // We systematically scan over all momentum integers (to avoid problems with Brillouin folding
int iKmin = -1000*N; int iKmin = -1000*N;
int iKmax = 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); 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;
ABACUSerror("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 ABACUSerror("Wrong number of arguments to Heis_DSF executable.");
*/
return(0); return(0);
} }

View File

@ -26,12 +26,14 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Heis_DSF executable: " << endl; cout << endl << "Usage of Heis_DSF executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 << "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 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 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 << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers "
//cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl; "defining the AveragingState; used as defaultScanStatename" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << 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 << "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 << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
@ -45,8 +47,6 @@ int main(int argc, char* argv[])
int N = atoi(argv[ctr++]); int N = atoi(argv[ctr++]);
int M = atoi(argv[ctr++]); int M = atoi(argv[ctr++]);
char* Ix2filenameprefix = argv[ctr++]; char* Ix2filenameprefix = argv[ctr++];
//int iKmin = atoi(argv[5]);
//int iKmax = atoi(argv[6]);
int Max_Secs = atoi(argv[ctr++]); int Max_Secs = atoi(argv[ctr++]);
DP target_sumrule = atof(argv[ctr++]); DP target_sumrule = atof(argv[ctr++]);
bool refine = (atoi(argv[ctr++]) == 1); bool refine = (atoi(argv[ctr++]) == 1);
@ -81,8 +81,6 @@ int main(int argc, char* argv[])
Ix2_input_file >> Nrap_read[level]; Ix2_input_file >> Nrap_read[level];
Ix2_read[level] = Vect<int> (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]; 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); } while (Ix2_input_file.peek() != EOF);
// Construct the Averaging State: // Construct the Averaging State:
@ -95,36 +93,41 @@ int main(int argc, char* argv[])
if (Delta > 0.0 && Delta < 1.0) { if (Delta > 0.0 && Delta < 1.0) {
XXZ_Bethe_State AveragingState (chain, base); XXZ_Bethe_State AveragingState (chain, base);
for (int il = 0; il < chain.Nstrings; ++il) { 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]; 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.Set_Label_from_Ix2(AveragingState.Ix2);
AveragingState.Compute_All(true); AveragingState.Compute_All(true);
//cout << "AveragingState read from file: " << AveragingState << endl;
// Perform the scan: // Perform the scan:
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors); Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax,
Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
} }
else if (Delta == 1.0) { else if (Delta == 1.0) {
XXX_Bethe_State AveragingState (chain, base); XXX_Bethe_State AveragingState (chain, base);
for (int il = 0; il < chain.Nstrings; ++il) { 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]; 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.Set_Label_from_Ix2(AveragingState.Ix2);
AveragingState.Compute_All(true); AveragingState.Compute_All(true);
// Perform the scan: // Perform the scan:
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors); Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax,
Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
} }
else if (Delta > 1.0) { else if (Delta > 1.0) {
XXZ_gpd_Bethe_State AveragingState (chain, base); XXZ_gpd_Bethe_State AveragingState (chain, base);
for (int il = 0; il < chain.Nstrings; ++il) { 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]; 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.Set_Label_from_Ix2(AveragingState.Ix2);
AveragingState.Compute_All(true); AveragingState.Compute_All(true);
// Perform the scan: // Perform the scan:
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors); Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax,
Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
} }
} }

View File

@ -29,13 +29,16 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Heis_DSF_par executable: " << 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 << "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 << 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 << "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 << "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 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 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 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 << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << endl << "EXAMPLE: " << endl << endl; cout << endl << "EXAMPLE: " << endl << endl;
cout << "mpiexec -np 8 Heis_DSF_par z 1.0 100 40 0 100 600" << endl << endl; cout << "mpiexec -np 8 Heis_DSF_par z 1.0 100 40 0 100 600" << endl << endl;
@ -77,14 +80,10 @@ int main(int argc, char *argv[])
while (tnow - tstart < Max_Secs - supercycle_time - 300) { // space for one more supercycle, + 5 minutes safety 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) if (rank == 0)
// Split up thread list into chunks, one per processor // Split up thread list into chunks, one per processor
Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors); 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 // 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: // to have finished splitting up the thr file into pieces before starting:
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
@ -93,8 +92,6 @@ int main(int argc, char *argv[])
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax,
supercycle_time, target_sumrule, refine, rank, nr_processors); supercycle_time, target_sumrule, refine, rank, nr_processors);
//cout << "rank " << rank << " finished scanning, reached wrapup stage." << endl;
// Another barrier synchronization // Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
@ -102,8 +99,6 @@ int main(int argc, char *argv[])
if (rank == 0) if (rank == 0)
Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors); Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors);
//cout << "rank " << rank << " passed wrapup stage." << endl;
// Another barrier synchronization // Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);

View File

@ -29,13 +29,17 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Heis_DSF_par_Prepare executable: " << endl; cout << endl << "Usage of Heis_DSF_par_Prepare executable: " << endl;
cout << endl << "This function prepares for ABACUSG in parallel mode, starting from a preexisting serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl; cout << endl << "This function prepares for ABACUSG 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 << 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 << "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 << "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 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 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 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 << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << 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; cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
@ -65,7 +69,8 @@ int main(int argc, char *argv[])
string defaultScanStatename = ""; string defaultScanStatename = "";
// Split up thread list into chunks, one per processor // 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); Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels,
nr_processors_lower_paralevels, nr_processors_at_newlevel);
} }

View File

@ -29,13 +29,16 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Heis_DSF_par_Run executable: " << 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 << "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 << 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 << "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 << "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 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 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 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 << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << 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 Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
@ -64,9 +67,6 @@ int main(int argc, char *argv[])
} }
Max_Secs = atoi(argv[n++]); Max_Secs = atoi(argv[n++]);
supercycle_time = atoi(argv[n++]); supercycle_time = atoi(argv[n++]);
//}
//DP supercycle_time = 600.0; // allotted time per supercycle
if (Max_Secs <= supercycle_time) ABACUSerror("Please allow more time in Heis_DSF_par_Run."); if (Max_Secs <= supercycle_time) ABACUSerror("Please allow more time in Heis_DSF_par_Run.");

View File

@ -13,7 +13,6 @@ Purpose: Parallel version of ABACUS using MPICH.
***********************************************************/ ***********************************************************/
#include "ABACUS.h" #include "ABACUS.h"
//#include "mpi.h" // not needed for Prepare or Wrapup
using namespace ABACUS; using namespace ABACUS;
@ -31,11 +30,13 @@ int main(int argc, char *argv[])
cout << endl << "Usage of Heis_DSF_par_Wrapup executable: " << endl; cout << endl << "Usage of Heis_DSF_par_Wrapup executable: " << endl;
cout << endl << "This function wraps up an ABACUSG parallel mode run." << endl; cout << endl << "This function wraps up an ABACUSG parallel mode run." << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 << "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 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 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 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 << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << 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; cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
@ -65,7 +66,8 @@ int main(int argc, char *argv[])
string defaultScanStatename = ""; string defaultScanStatename = "";
// Split up thread list into chunks, one per processor // 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); Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels,
nr_processors_lower_paralevels, nr_processors_at_newlevel);
} }

View File

@ -27,11 +27,9 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; 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 << "Usage of LiebLin_Catalogue_Fixed_c_k_Nscaling executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 kBT \t\t Temperature (positive only of course)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl; cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
@ -47,11 +45,8 @@ int main(int argc, char* argv[])
DP target_sumrule = atof(argv[ia++]); DP target_sumrule = atof(argv[ia++]);
int Max_Secs = atoi(argv[ia++]); int Max_Secs = atoi(argv[ia++]);
//clock_t StartTime = clock();
double StartTime = omp_get_wtime(); double StartTime = omp_get_wtime();
//clock_t ActualTime = StartTime;
double ActualTime = omp_get_wtime(); double ActualTime = omp_get_wtime();
int Secs_left = Max_Secs; int Secs_left = Max_Secs;
@ -99,7 +94,6 @@ int main(int argc, char* argv[])
ActualTime = omp_get_wtime(); ActualTime = omp_get_wtime();
//Secs_left = int(60*Max_minutes - double(ActualTime - StartTime)/CLOCKS_PER_SEC);
Secs_left = int(Max_Secs - (ActualTime - StartTime)); Secs_left = int(Max_Secs - (ActualTime - StartTime));
cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl; cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl;

View File

@ -26,11 +26,13 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl; cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 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 << "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 << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << 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 << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
@ -51,9 +53,6 @@ int main(int argc, char* argv[])
DP target_sumrule = atof(argv[9]); DP target_sumrule = atof(argv[9]);
bool refine = (atoi(argv[10]) == 1); 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); Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine);
} }

View File

@ -26,13 +26,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl; cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 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 << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the "
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl; "AveragingState; used as defaultScanStatename" << endl;
//cout << "DP kBT \t\t Temperature (positive only of course)" << 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 Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << 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 << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
@ -49,7 +51,6 @@ int main(int argc, char* argv[])
char* Ix2filenameprefix = argv[n++]; char* Ix2filenameprefix = argv[n++];
int iKmin = atoi(argv[n++]); int iKmin = atoi(argv[n++]);
int iKmax = atoi(argv[n++]); int iKmax = atoi(argv[n++]);
//DP kBT = atof(argv[n++]);
int Max_Secs = atoi(argv[n++]); int Max_Secs = atoi(argv[n++]);
DP target_sumrule = atof(argv[n++]); DP target_sumrule = atof(argv[n++]);
bool refine = (atoi(argv[n++]) == 1); bool refine = (atoi(argv[n++]) == 1);
@ -70,7 +71,6 @@ int main(int argc, char* argv[])
} }
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
Ix2_input_file >> Ix2_input[i]; Ix2_input_file >> Ix2_input[i];
//cout << i << "\t" << Ix2_input[i] << endl;
} }
// Now define the AveragingState // Now define the AveragingState
@ -78,16 +78,6 @@ int main(int argc, char* argv[])
AveragingState.Ix2 = Ix2_input; AveragingState.Ix2 = Ix2_input;
AveragingState.Compute_All(true); 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); Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine);
} }

View File

@ -30,15 +30,18 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_par_Prepare executable: " << 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 << "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 << 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 << "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 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 << "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 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 << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the "
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl; "AveragingState; used as defaultScanStatename" << endl;
//cout << "DP kBT \t\t Temperature (positive only of course)" << 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 << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << 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; cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
@ -55,7 +58,6 @@ int main(int argc, char *argv[])
Ix2filenameprefix = argv[n++]; Ix2filenameprefix = argv[n++];
iKmin = atoi(argv[n++]); iKmin = atoi(argv[n++]);
iKmax = 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 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)) ABACUSerror("Wrong nr of arguments in LiebLin_DSF_GeneralState_par_Prepare."); if (argc != 10 + 2*(paralevel - 1)) ABACUSerror("Wrong nr of arguments in LiebLin_DSF_GeneralState_par_Prepare.");
@ -75,28 +77,11 @@ int main(int argc, char *argv[])
stringstream filenamestrstream; stringstream filenamestrstream;
filenamestrstream << Ix2filenameprefix; filenamestrstream << Ix2filenameprefix;
string defaultScanStatename = filenamestrstream.str(); 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;
ABACUSerror("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 // 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); 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);
} }

View File

@ -30,24 +30,25 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_par executable: " << 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 << "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 << 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 << "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 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 << "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 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 << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the "
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl; "AveragingState; used as defaultScanStatename" << endl;
//cout << "DP kBT \t\t Temperature (positive only of course)" << 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 << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << 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 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); return(0);
} }
//else { // correct nr of arguments
int n = 1; int n = 1;
whichDSF = *argv[n++]; whichDSF = *argv[n++];
c_int = atof(argv[n++]); c_int = atof(argv[n++]);
@ -56,7 +57,6 @@ int main(int argc, char *argv[])
Ix2filenameprefix = argv[n++]; Ix2filenameprefix = argv[n++];
iKmin = atoi(argv[n++]); iKmin = atoi(argv[n++]);
iKmax = 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 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)) ABACUSerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare."); if (argc != 10 + 2*(paralevel - 1)) ABACUSerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
Vect<int> rank_lower_paralevels(paralevel - 1); Vect<int> rank_lower_paralevels(paralevel - 1);
@ -66,10 +66,6 @@ int main(int argc, char *argv[])
nr_processors_lower_paralevels[i] = atoi(argv[n++]); nr_processors_lower_paralevels[i] = atoi(argv[n++]);
} }
Max_Secs = 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) ABACUSerror("Please allow more time in LiebLin_DSF_par_Run."); if (Max_Secs <= 120) ABACUSerror("Please allow more time in LiebLin_DSF_par_Run.");
@ -98,7 +94,6 @@ int main(int argc, char *argv[])
} }
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
Ix2_input_file >> Ix2_input[i]; Ix2_input_file >> Ix2_input[i];
//cout << i << "\t" << Ix2_input[i] << endl;
} }
// Now define the AveragingState // Now define the AveragingState
@ -126,17 +121,14 @@ int main(int argc, char *argv[])
DP tnow = MPI::Wtime(); 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) { if (Max_Secs_used > 0) {
// Barrier synchronization // Barrier synchronization
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk ! // then everybody gets going on their own chunk !
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs,
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, target_sumrule, refine, paralevel, rank, nr_processors);
// 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 // Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);

View File

@ -32,13 +32,15 @@ int main(int argc, char *argv[])
cout << endl << "Usage of LiebLin_DSF_par_Wrapup executable: " << 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 << "This function wraps up an ABACUS parallel mode run." << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 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 << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the "
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl; "AveragingState; used as defaultScanStatename" << endl;
//cout << "DP kBT \t\t Temperature (positive only of course)" << 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 << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << 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; cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
@ -55,7 +57,6 @@ int main(int argc, char *argv[])
Ix2filenameprefix = argv[n++]; Ix2filenameprefix = argv[n++];
iKmin = atoi(argv[n++]); iKmin = atoi(argv[n++]);
iKmax = 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 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)) ABACUSerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare."); if (argc != 10 + 2*(paralevel - 1)) ABACUSerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
@ -73,28 +74,11 @@ int main(int argc, char *argv[])
stringstream filenamestrstream; stringstream filenamestrstream;
filenamestrstream << Ix2filenameprefix; filenamestrstream << Ix2filenameprefix;
string defaultScanStatename = filenamestrstream.str(); 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;
ABACUSerror("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: // 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); 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);
} }

View File

@ -26,15 +26,16 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_MosesState executable: " << endl; cout << endl << "Usage of LiebLin_DSF_MosesState executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 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 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 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 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 iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl; "recommended values: -2*N and 2*N" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << 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 << "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 << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
@ -48,12 +49,10 @@ int main(int argc, char* argv[])
DP L = atof(argv[3]); DP L = atof(argv[3]);
int N = atoi(argv[4]); int N = atoi(argv[4]);
int Nl = atoi(argv[5]); int Nl = atoi(argv[5]);
//int Nr = N - Nl;
int DIl = atoi(argv[6]); int DIl = atoi(argv[6]);
int DIr = atoi(argv[7]); int DIr = atoi(argv[7]);
int iKmin = atoi(argv[8]); int iKmin = atoi(argv[8]);
int iKmax = atoi(argv[9]); int iKmax = atoi(argv[9]);
//DP kBT = atof(argv[7]);
int Max_Secs = atoi(argv[10]); int Max_Secs = atoi(argv[10]);
DP target_sumrule = atof(argv[11]); DP target_sumrule = atof(argv[11]);
bool refine = (atoi(argv[12]) == 1); bool refine = (atoi(argv[12]) == 1);
@ -67,8 +66,6 @@ int main(int argc, char* argv[])
MosesState.Compute_All (true); MosesState.Compute_All (true);
//cout << MosesState << endl;
// Handy default name: // Handy default name:
stringstream defaultScanStatename_strstream; stringstream defaultScanStatename_strstream;
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr; defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;

View File

@ -31,16 +31,19 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_MosesState_par executable: " << 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 << "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 << 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 << "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 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 << "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 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 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 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 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 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 Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl; cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
cout << endl << "EXAMPLE: " << endl << endl; cout << endl << "EXAMPLE: " << endl << endl;
@ -63,8 +66,6 @@ int main(int argc, char *argv[])
supercycle_time = atoi(argv[11]); supercycle_time = atoi(argv[11]);
} }
//DP supercycle_time = 600.0; // allotted time per supercycle
if (Max_Secs <= supercycle_time) ABACUSerror("Please allow more time in LiebLin_DSF_par."); if (Max_Secs <= supercycle_time) ABACUSerror("Please allow more time in LiebLin_DSF_par.");
MPI::Init(argc, argv); MPI::Init(argc, argv);
@ -103,7 +104,6 @@ int main(int argc, char *argv[])
if (rank == 0) if (rank == 0)
// Split up thread list into chunks, one per processor // 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); 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 // Barrier synchronization, to make sure other processes wait for process of rank 0
@ -111,9 +111,8 @@ int main(int argc, char *argv[])
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk ! // then everybody gets going on their own chunk !
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time,
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, supercycle_time, target_sumrule, refine, rank, nr_processors); target_sumrule, refine, rank, nr_processors);
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time, target_sumrule, refine, rank, nr_processors);
// Another barrier synchronization // Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
@ -121,7 +120,6 @@ int main(int argc, char *argv[])
// Now that everybody is done, digest data into unique files // Now that everybody is done, digest data into unique files
if (rank == 0) 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); Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
// Another barrier synchronization // Another barrier synchronization

View File

@ -31,16 +31,19 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Prepare executable: " << 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 << "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 << 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 << "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 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 << "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 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 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 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 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 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 << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << 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; cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
@ -86,7 +89,9 @@ int main(int argc, char *argv[])
// Split up thread list into chunks, one per processor // 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); 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);
} }

View File

@ -31,16 +31,19 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Run executable: " << 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 << "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 << 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 << "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 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 << "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 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 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 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 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 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 << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << 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 Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
@ -70,9 +73,6 @@ int main(int argc, char *argv[])
} }
Max_Secs = atoi(argv[n++]); Max_Secs = atoi(argv[n++]);
supercycle_time = atoi(argv[n++]); supercycle_time = atoi(argv[n++]);
//}
//DP supercycle_time = 600.0; // allotted time per supercycle
if (Max_Secs <= supercycle_time) ABACUSerror("Please allow more time in LiebLin_DSF_par_Run."); if (Max_Secs <= supercycle_time) ABACUSerror("Please allow more time in LiebLin_DSF_par_Run.");
@ -83,8 +83,6 @@ int main(int argc, char *argv[])
int rank_here = MPI::COMM_WORLD.Get_rank(); int rank_here = MPI::COMM_WORLD.Get_rank();
int nr_processors_here = MPI::COMM_WORLD.Get_size(); 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> rank (paralevel);
Vect<int> nr_processors (paralevel); Vect<int> nr_processors (paralevel);
for (int i = 0; i < paralevel - 1; ++i) { for (int i = 0; i < paralevel - 1; ++i) {
@ -117,35 +115,18 @@ int main(int argc, char *argv[])
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr; defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
string defaultScanStatename = defaultScanStatename_strstream.str(); string defaultScanStatename = defaultScanStatename_strstream.str();
//cout << "rank " << rank_here << " out of " << nr_processors_here << " waiting at barrier." << endl;
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety 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 // 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: // to have finished splitting up the thr file into pieces before starting:
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk ! // then everybody gets going on their own chunk !
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time,
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors); 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 // Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);

View File

@ -33,14 +33,16 @@ int main(int argc, char *argv[])
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Wrapup executable: " << 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 << "This function wraps up an ABACUS parallel mode run." << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 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 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 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 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 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 << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << 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; cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
@ -86,7 +88,9 @@ int main(int argc, char *argv[])
// Digest files into a unique one for the latest paralevel: // 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); 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);
} }

View File

@ -26,15 +26,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl; cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 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 << "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 << "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 << "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 << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
cout << endl << "EXAMPLE: " << endl << 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; cout << "LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 0.56 10 600 0" << endl << endl;
@ -48,7 +48,6 @@ int main(int argc, char* argv[])
int iKmin = atoi(argv[5]); int iKmin = atoi(argv[5]);
int iKmax = atoi(argv[6]); int iKmax = atoi(argv[6]);
DP kBT = atof(argv[7]); DP kBT = atof(argv[7]);
//int nstates_req = atoi(argv[8]);
int Max_Secs = atoi(argv[8]); int Max_Secs = atoi(argv[8]);
bool refine = (atoi(argv[9]) == 1); bool refine = (atoi(argv[9]) == 1);
@ -57,13 +56,11 @@ int main(int argc, char* argv[])
LiebLin_Diagonal_State_Ensemble ensemble; LiebLin_Diagonal_State_Ensemble ensemble;
stringstream ensfilestrstream; 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"; ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
string ensfilestr = ensfilestrstream.str(); string ensfilestr = ensfilestrstream.str();
const char* ensfile_Cstr = ensfilestr.c_str(); const char* ensfile_Cstr = ensfilestr.c_str();
if (!refine) { // Construct the state ensemble 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 = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT);
ensemble.Save(ensfile_Cstr); // Save the ensemble ensemble.Save(ensfile_Cstr); // Save the ensemble
} }
@ -75,10 +72,8 @@ int main(int argc, char* argv[])
// Now perform the DSF calculation over each state in the ensemble, distributing the time according to the weight // 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) { for (int ns = 0; ns < ensemble.nstates; ++ns) {
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax, Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax,
//int Max_Secs, DP target_sumrule, bool refine, int rank, int nr_processors) int(Max_Secs * ensemble.weight[ns]), 1.0e+6, refine);
//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 // Evaluate the f-sumrule

View File

@ -27,15 +27,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl; cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 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 << "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 << "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 << "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 << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
cout << endl << "EXAMPLE: " << endl << 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; cout << "LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 0.56 10 600 0" << endl << endl;
@ -49,7 +49,6 @@ int main(int argc, char* argv[])
int iKmin = atoi(argv[5]); int iKmin = atoi(argv[5]);
int iKmax = atoi(argv[6]); int iKmax = atoi(argv[6]);
DP kBT = atof(argv[7]); DP kBT = atof(argv[7]);
//int nstates_req = atoi(argv[8]);
int Max_Secs = atoi(argv[8]); int Max_Secs = atoi(argv[8]);
bool refine = (atoi(argv[9]) == 1); bool refine = (atoi(argv[9]) == 1);
@ -70,13 +69,11 @@ int main(int argc, char* argv[])
LiebLin_Diagonal_State_Ensemble ensemble; LiebLin_Diagonal_State_Ensemble ensemble;
stringstream ensfilestrstream; 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"; ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
string ensfilestr = ensfilestrstream.str(); string ensfilestr = ensfilestrstream.str();
const char* ensfile_Cstr = ensfilestr.c_str(); const char* ensfile_Cstr = ensfilestr.c_str();
if (!refine) { // Construct the state ensemble 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 = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT);
ensemble.Save(ensfile_Cstr); // Save the ensemble ensemble.Save(ensfile_Cstr); // Save the ensemble
} }
@ -89,30 +86,6 @@ int main(int argc, char* argv[])
// Now perform the DSF calculation over each state in the ensemble // 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) ABACUSerror("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; int Max_Secs_used = Max_Secs/ensemble.nstates;
DP supercycle_time = 600.0; // allotted time per supercycle DP supercycle_time = 600.0; // allotted time per supercycle
@ -131,7 +104,6 @@ int main(int argc, char* argv[])
if (rank == 0) if (rank == 0)
// Split up thread list into chunks, one per processor // 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); 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 // Barrier synchronization, to make sure other processes wait for process of rank 0
@ -139,9 +111,6 @@ int main(int argc, char* argv[])
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk ! // 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); Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, supercycle_time, 1.0e+6, refine, rank, nr_processors);
// Another barrier synchronization // Another barrier synchronization
@ -150,7 +119,6 @@ int main(int argc, char* argv[])
// Now that everybody is done, digest data into unique files // Now that everybody is done, digest data into unique files
if (rank == 0) 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); Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
// Another barrier synchronization // Another barrier synchronization

View File

@ -29,13 +29,16 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_par executable: " << 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 << "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 << 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 << "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 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 << "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 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 << "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 << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << 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 << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
@ -57,8 +60,6 @@ int main(int argc, char *argv[])
supercycle_time = atoi(argv[9]); supercycle_time = atoi(argv[9]);
} }
//DP supercycle_time = 600.0; // allotted time per supercycle
if (Max_Secs <= supercycle_time) ABACUSerror("Please allow more time in LiebLin_DSF_par."); if (Max_Secs <= supercycle_time) ABACUSerror("Please allow more time in LiebLin_DSF_par.");
MPI::Init(argc, argv); MPI::Init(argc, argv);
@ -83,7 +84,6 @@ int main(int argc, char *argv[])
if (rank == 0) if (rank == 0)
// Split up thread list into chunks, one per processor // 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); 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 // Barrier synchronization, to make sure other processes wait for process of rank 0
@ -91,9 +91,8 @@ int main(int argc, char *argv[])
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk ! // 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, Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
supercycle_time, target_sumrule, refine, rank, nr_processors); supercycle_time, target_sumrule, refine, rank, nr_processors);
// Another barrier synchronization // Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
@ -101,7 +100,6 @@ int main(int argc, char *argv[])
// Now that everybody is done, digest data into unique files // Now that everybody is done, digest data into unique files
if (rank == 0) 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); Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
// Another barrier synchronization // Another barrier synchronization

View File

@ -29,13 +29,16 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_par_Prepare executable: " << 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 << "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 << 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 << "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 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 << "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 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 << "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 << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int paralevel" << endl; cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl; cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
@ -67,7 +70,9 @@ int main(int argc, char *argv[])
string defaultScanStatename = ""; string defaultScanStatename = "";
// Split up thread list into chunks, one per processor // 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); 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);
} }

View File

@ -29,13 +29,16 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_par_Run executable: " << 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 << "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 << 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 << "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 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 << "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 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 << "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 << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int paralevel" << endl; cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl; cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
@ -101,7 +104,6 @@ int main(int argc, char *argv[])
MPI_Barrier (MPI::COMM_WORLD); MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk ! // 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, Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
Max_Secs_used, target_sumrule, refine, paralevel, rank, nr_processors); Max_Secs_used, target_sumrule, refine, paralevel, rank, nr_processors);

View File

@ -31,11 +31,13 @@ int main(int argc, char *argv[])
cout << endl << "Usage of LiebLin_DSF_par_Wrapup executable: " << 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 << "This function wraps up an ABACUS parallel mode run." << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 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 << "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 << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int paralevel" << endl; cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl; cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
@ -67,7 +69,9 @@ int main(int argc, char *argv[])
string defaultScanStatename = ""; string defaultScanStatename = "";
// Digest files into a unique one for the latest paralevel: // 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); 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);
} }

View File

@ -26,7 +26,8 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl; cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 N \t\t\t Number of particles: use positive integer values only" << endl;
@ -42,13 +43,7 @@ int main(int argc, char* argv[])
int N = atoi(argv[4]); int N = atoi(argv[4]);
DP kBT = atof(argv[5]); DP kBT = atof(argv[5]);
//if (whichDSF != 'd') ABACUSerror("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: // 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); LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
spstate.Compute_All(true); spstate.Compute_All(true);
@ -74,11 +69,14 @@ int main(int argc, char* argv[])
cout << spstate << endl; cout << spstate << endl;
cout << estate; cout << estate;
if (whichDSF == 'd') if (whichDSF == 'd')
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Density_ME(spstate, estate))) << endl; cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E
<< "\tME = " << real(exp(ln_Density_ME(spstate, estate))) << endl;
else if (whichDSF == 'o') else if (whichDSF == 'o')
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(estate, spstate))) << endl; cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E
<< "\tME = " << real(exp(ln_Psi_ME(estate, spstate))) << endl;
else if (whichDSF == 'g') 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 << 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; //cout << "Another try ? (1 == yes, 0 == no)" << endl;
again = 1; again = 1;

View File

@ -26,7 +26,8 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl; cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 N \t\t\t Number of particles: use positive integer values only" << endl;
@ -42,13 +43,7 @@ int main(int argc, char* argv[])
int N = atoi(argv[4]); int N = atoi(argv[4]);
DP kBT = atof(argv[5]); DP kBT = atof(argv[5]);
//if (whichDSF != 'd') ABACUSerror("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: // 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); LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
spstate.Compute_All(true); spstate.Compute_All(true);
@ -74,11 +69,14 @@ int main(int argc, char* argv[])
cout << spstate << endl; cout << spstate << endl;
cout << estate; cout << estate;
if (whichDSF == 'd') if (whichDSF == 'd')
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Density_ME(spstate, estate))) << endl; cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E
<< "\tME = " << real(exp(ln_Density_ME(spstate, estate))) << endl;
else if (whichDSF == 'o') else if (whichDSF == 'o')
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(estate, spstate))) << endl; cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E
<< "\tME = " << real(exp(ln_Psi_ME(estate, spstate))) << endl;
else if (whichDSF == 'g') 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 << 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; cout << "Another try ? (1 == yes, 0 == no)" << endl;
again = 1; again = 1;

View File

@ -27,13 +27,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_Data_Daemon executable: " << endl; cout << endl << "Usage of LiebLin_Data_Daemon executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 << "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 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 << "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 << "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 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 << "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 << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int Max_Hrs \t\t Allowed computational time: (in hours)" << endl; cout << "int Max_Hrs \t\t Allowed computational time: (in hours)" << endl;
} }
@ -52,21 +54,17 @@ int main(int argc, char* argv[])
int Max_Hrs = atoi(argv[ia++]); int Max_Hrs = atoi(argv[ia++]);
// Individual computations are split into chuncks of Max_Hrs/(Nc * 4) // 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 int Max_Secs = (Max_Hrs * 2700)/Nc; // to minimize wrapping up & restarting time
cout << "Data daemon will use chunks of " << Max_Secs << " seconds." << endl; cout << "Data daemon will use chunks of " << Max_Secs << " seconds." << endl;
//clock_t StartTime = clock();
double StartTime = omp_get_wtime(); double StartTime = omp_get_wtime();
//clock_t ActualTime = StartTime;
double ActualTime = omp_get_wtime(); double ActualTime = omp_get_wtime();
DP c_int; DP c_int;
DP target_sumrule = 1.0; 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)) { while (ActualTime - StartTime < double(3600 * Max_Hrs - Max_Secs)) {
Vect<DP> srsat(0.0, Nc); Vect<DP> srsat(0.0, Nc);
@ -101,13 +99,12 @@ int main(int argc, char* argv[])
} // for ic } // for ic
cout << "srsat min found: " << srmin << "\t for c = " << c_int_max/pow(cfact, icmin) << ". Now refining this." 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; << " Time left: " << 3600* Max_Hrs - (ActualTime - StartTime) << " seconds." << endl;
// Improve the icmin calculation by one chunk: // 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]); 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(); ActualTime = omp_get_wtime();
} // while there is time } // while there is time

View File

@ -27,11 +27,13 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_Data_Daemon_Nscaling executable: " << endl; cout << endl << "Usage of LiebLin_Data_Daemon_Nscaling executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 "
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; "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 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 kBT \t\t Temperature (positive only of course)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << 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; cout << "int Max_minutes \t\t Allowed computational time: (in minutes)" << endl;
@ -48,11 +50,8 @@ int main(int argc, char* argv[])
DP target_sumrule = atof(argv[ia++]); DP target_sumrule = atof(argv[ia++]);
int Max_minutes = atoi(argv[ia++]); int Max_minutes = atoi(argv[ia++]);
//clock_t StartTime = clock();
double StartTime = omp_get_wtime(); double StartTime = omp_get_wtime();
//clock_t ActualTime = StartTime;
double ActualTime = omp_get_wtime(); double ActualTime = omp_get_wtime();
int Secs_left = 60* Max_minutes; int Secs_left = 60* Max_minutes;
@ -91,7 +90,6 @@ int main(int argc, char* argv[])
ActualTime = clock(); ActualTime = clock();
//Secs_left = int(60*Max_minutes - double(ActualTime - StartTime)/CLOCKS_PER_SEC);
Secs_left = int(60*Max_minutes - (ActualTime - StartTime)); Secs_left = int(60*Max_minutes - (ActualTime - StartTime));
cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl; cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl;

View File

@ -25,7 +25,8 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_Fourier_to_Qsqx executable: " << endl; cout << endl << "Usage of LiebLin_Fourier_to_Qsqx executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl; cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl; cout << "int N \t\t\t Number of particles" << endl;
@ -43,8 +44,6 @@ int main(int argc, char* argv[])
int iKmax = atoi(argv[6]); int iKmax = atoi(argv[6]);
DP kBT = atof(argv[7]); DP kBT = atof(argv[7]);
int Npts_x = atoi(argv[8]); int Npts_x = atoi(argv[8]);
// Force Npts_x
//Npts_x = L;
if (whichDSF != 'd') ABACUSerror("Must use whichDSF == d in LiebLin_Fourier_ssf_to_Qsqx"); if (whichDSF != 'd') ABACUSerror("Must use whichDSF == d in LiebLin_Fourier_ssf_to_Qsqx");
@ -137,7 +136,6 @@ int main(int argc, char* argv[])
// Output to file: // Output to file:
for (int ix = 0; ix < Npts_x; ++ix) { for (int ix = 0; ix < Npts_x; ++ix) {
if (ix > 0) SFT_outfile << endl; 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 << xlattice[ix]/L << "\t" << FT[ix];
} }

View File

@ -25,7 +25,8 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; 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 << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl; cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl; cout << "int N \t\t\t Number of particles" << endl;

View File

@ -25,12 +25,12 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; 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 << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl; cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << 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 << "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 << "RAW file name" << endl;
cout << "int Npts_t \t Number of points in time for the Fourier transform" << 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; cout << "DP t_max \t Max time to be used" << endl;
@ -43,7 +43,6 @@ int main(int argc, char* argv[])
int N = atoi(argv[4]); int N = atoi(argv[4]);
int iKmin = atoi(argv[5]); int iKmin = atoi(argv[5]);
int iKmax = atoi(argv[6]); int iKmax = atoi(argv[6]);
//DP kBT = atof(argv[7]);
char* rawfilename = argv[7]; char* rawfilename = argv[7];
int Npts_t = atoi(argv[8]); int Npts_t = atoi(argv[8]);
DP t_max = atof(argv[9]); DP t_max = atof(argv[9]);
@ -52,10 +51,8 @@ int main(int argc, char* argv[])
if (iKmin != 0) ABACUSerror("LiebLin_Fourier_to_t_equal_x only implemented for raw files with iKmin == 0."); if (iKmin != 0) ABACUSerror("LiebLin_Fourier_to_t_equal_x only implemented for raw files with iKmin == 0.");
ifstream RAW_infile; ifstream RAW_infile;
//RAW_infile.open(RAW_Cstr);
RAW_infile.open(rawfilename); RAW_infile.open(rawfilename);
if (RAW_infile.fail()) { if (RAW_infile.fail()) {
//cout << RAW_Cstr << endl;
cout << rawfilename << endl; cout << rawfilename << endl;
ABACUSerror("Could not open RAW_infile... "); ABACUSerror("Could not open RAW_infile... ");
} }
@ -74,7 +71,6 @@ int main(int argc, char* argv[])
DP omega; DP omega;
int iK; int iK;
DP FF; DP FF;
//int conv;
DP dev; DP dev;
string label; string label;

View File

@ -25,7 +25,8 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; 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 << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl; cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl; cout << "int N \t\t\t Number of particles" << endl;
@ -43,8 +44,6 @@ int main(int argc, char* argv[])
int iKmax = atoi(argv[6]); int iKmax = atoi(argv[6]);
DP kBT = atof(argv[7]); DP kBT = atof(argv[7]);
int Npts_x = atoi(argv[8]); int Npts_x = atoi(argv[8]);
// Force Npts_x
//Npts_x = L;
stringstream filenameprefix; stringstream filenameprefix;
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, "");
@ -85,7 +84,6 @@ int main(int argc, char* argv[])
DP omega; DP omega;
int iK; int iK;
DP FF; DP FF;
//int conv;
DP dev; DP dev;
string label; string label;
@ -174,7 +172,8 @@ int main(int argc, char* argv[])
FTimavg[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; 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: // Output to file:
for (int ix = 0; ix < Npts_x; ++ix) { for (int ix = 0; ix < Npts_x; ++ix) {

View File

@ -25,12 +25,12 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; 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 << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl; cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << 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 << "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 << "RAW file name" << endl;
cout << "int Npts_x Number of points in space for the Fourier transform" << endl; cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
} }
@ -42,24 +42,12 @@ int main(int argc, char* argv[])
int N = atoi(argv[4]); int N = atoi(argv[4]);
int iKmin = atoi(argv[5]); int iKmin = atoi(argv[5]);
int iKmax = atoi(argv[6]); int iKmax = atoi(argv[6]);
//DP kBT = atof(argv[7]);
char* rawfilename = argv[7]; char* rawfilename = argv[7];
int Npts_x = atoi(argv[8]); 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; ifstream RAW_infile;
//RAW_infile.open(RAW_Cstr);
RAW_infile.open(rawfilename); RAW_infile.open(rawfilename);
if (RAW_infile.fail()) { if (RAW_infile.fail()) {
//cout << RAW_Cstr << endl;
cout << rawfilename << endl; cout << rawfilename << endl;
ABACUSerror("Could not open RAW_infile... "); ABACUSerror("Could not open RAW_infile... ");
} }
@ -80,7 +68,6 @@ int main(int argc, char* argv[])
DP omega; DP omega;
int iK; int iK;
DP FF; DP FF;
//int conv;
DP dev; DP dev;
string label; string label;
@ -135,7 +122,6 @@ int main(int argc, char* argv[])
// Output to file: // Output to file:
for (int ix = 0; ix < Npts_x; ++ix) { for (int ix = 0; ix < Npts_x; ++ix) {
if (ix > 0) SFT_outfile << endl; 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 << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix];
} }

View File

@ -26,7 +26,8 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl; cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 N \t\t\t Number of particles: use positive integer values only" << endl;
@ -41,7 +42,6 @@ int main(int argc, char* argv[])
DP L = atof(argv[3]); DP L = atof(argv[3]);
int N = atoi(argv[4]); int N = atoi(argv[4]);
int Nl = atoi(argv[5]); int Nl = atoi(argv[5]);
//int Nr = N - Nl;
int DIl = atoi(argv[6]); int DIl = atoi(argv[6]);
int DIr = atoi(argv[7]); int DIr = atoi(argv[7]);
@ -67,7 +67,8 @@ int main(int argc, char* argv[])
for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new; for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new;
estate.Compute_All(false); estate.Compute_All(false);
cout << estate; cout << estate;
cout << setprecision(16) << "omega = " << estate.E - MosesState.E << "\t" << exp(real(ln_Density_ME(MosesState, estate))) << endl; cout << setprecision(16) << "omega = " << estate.E - MosesState.E << "\t"
<< exp(real(ln_Density_ME(MosesState, estate))) << endl;
cout << "Another try ? (0 == no)" << endl; cout << "Another try ? (0 == no)" << endl;
cin >> again; cin >> again;
} while (again != 0); } while (again != 0);

View File

@ -27,11 +27,13 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_RAW_File_Stats executable: " << endl; cout << endl << "Usage of LiebLin_RAW_File_Stats executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 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 << "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 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 << "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 << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int Aggregate size" << endl; cout << "int Aggregate size" << endl;
} }
@ -74,7 +76,6 @@ int main(int argc, char* argv[])
LiebLin_Bethe_State AveragingState = Canonical_Saddle_Point_State (c_int, L, N, whichDSF == 'Z' ? 0.0 : kBT); LiebLin_Bethe_State AveragingState = Canonical_Saddle_Point_State (c_int, L, N, whichDSF == 'Z' ? 0.0 : kBT);
DP Chem_Pot = Chemical_Potential (AveragingState); 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); Vect<DP> sumrule_factor(iKmax - iKmin + 1);
for (int ik = 0; ik < iKmax - iKmin + 1; ++ik) for (int ik = 0; ik < iKmax - iKmin + 1; ++ik)
sumrule_factor[ik] = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, ik, ik); sumrule_factor[ik] = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, ik, ik);
@ -117,7 +118,8 @@ int main(int argc, char* argv[])
} }
if (naccounted >= AgSize) { if (naccounted >= AgSize) {
STATfile << nread << "\t" << maxsrcont << "\t" << totsrcont/AgSize << "\t" << totsrcont/(AgSize * (maxsrcont > 0.0 ? maxsrcont : 1.0)) << "\t" << accumulatedsrcont << endl; STATfile << nread << "\t" << maxsrcont << "\t" << totsrcont/AgSize << "\t"
<< totsrcont/(AgSize * (maxsrcont > 0.0 ? maxsrcont : 1.0)) << "\t" << accumulatedsrcont << endl;
naccounted = 0; naccounted = 0;
maxsrcont = 0.0; maxsrcont = 0.0;
totsrcont = 0.0; totsrcont = 0.0;

View File

@ -19,8 +19,6 @@ using namespace ABACUS;
int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
//if (argc != 7) ABACUSerror("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) ABACUSerror("Wrong number of arguments. Use c(best to set to 1), mu, kBT, req_diff, Max_Secs"); if (argc != 6) ABACUSerror("Wrong number of arguments. Use c(best to set to 1), mu, kBT, req_diff, Max_Secs");
DP c_int = atof(argv[1]); DP c_int = atof(argv[1]);
@ -33,11 +31,8 @@ int main(int argc, const char* argv[])
if (kBT <= 0.0) ABACUSerror("Negative T ? Not for the LiebLin gas."); if (kBT <= 0.0) ABACUSerror("Negative T ? Not for the LiebLin gas.");
if (Max_Secs < 10) ABACUSerror("Give more time."); if (Max_Secs < 10) ABACUSerror("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); LiebLin_TBA_Solution solution(c_int, mu, kBT, req_diff, Max_Secs);
cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t"; cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
return(0); return(0);

View File

@ -19,8 +19,6 @@ using namespace ABACUS;
int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
//if (argc != 7) ABACUSerror("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) ABACUSerror("Wrong number of arguments. Use c(best to set to 1), nbar, kBT, req_diff, Max_Secs"); if (argc != 6) ABACUSerror("Wrong number of arguments. Use c(best to set to 1), nbar, kBT, req_diff, Max_Secs");
DP c_int = atof(argv[1]); DP c_int = atof(argv[1]);
@ -33,8 +31,6 @@ int main(int argc, const char* argv[])
if (kBT <= 0.0) ABACUSerror("Negative T ? Not for the LiebLin gas."); if (kBT <= 0.0) ABACUSerror("Negative T ? Not for the LiebLin gas.");
if (Max_Secs < 10) ABACUSerror("Give more time."); if (Max_Secs < 10) ABACUSerror("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); 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"; cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";

View File

@ -19,8 +19,8 @@ using namespace ABACUS;
int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
if (argc != 7) ABACUSerror("Wrong number of arguments. Use c(best to set to 1), "
if (argc != 7) ABACUSerror("Wrong number of arguments. Use c(best to set to 1), nbar, ebar, req_diff, Max_Secs, bool Save_data (0 == false)."); "nbar, ebar, req_diff, Max_Secs, bool Save_data (0 == false).");
DP c_int = atof(argv[1]); DP c_int = atof(argv[1]);
DP nbar = atof(argv[2]); DP nbar = atof(argv[2]);
@ -32,8 +32,6 @@ int main(int argc, const char* argv[])
if (c_int <= 0.0) ABACUSerror("Give a strictly positive c."); if (c_int <= 0.0) ABACUSerror("Give a strictly positive c.");
if (Max_Secs < 10) ABACUSerror("Give more time."); if (Max_Secs < 10) ABACUSerror("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); 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"; cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";

View File

@ -26,11 +26,13 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << "Usage of ODSLF_DSF executable: " << endl; cout << "Usage of ODSLF_DSF executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 << "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 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 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 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 << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << 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 << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
@ -52,7 +54,6 @@ int main(int argc, char* argv[])
Scan_ODSLF (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine, 0, 1); Scan_ODSLF (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine, 0, 1);
} }
else ABACUSerror("Wrong number of arguments to ODSLF_DSF executable."); else ABACUSerror("Wrong number of arguments to ODSLF_DSF executable.");
return(0); return(0);

View File

@ -29,8 +29,6 @@ int main(int argc, char* argv[])
char whichDSF = *argv[2]; char whichDSF = *argv[2];
char whichsorting = *argv[3]; char whichsorting = *argv[3];
//cout << rawfilename << "\t" << whichDSF << "\t" << whichsorting << endl;
Sort_RAW_File (rawfilename, whichsorting, whichDSF); Sort_RAW_File (rawfilename, whichsorting, whichDSF);
return(0); return(0);

View File

@ -82,7 +82,8 @@ int main(int argc, char* argv[])
naccounted++; naccounted++;
if (naccounted >= AgSize) { if (naccounted >= AgSize) {
STATfile << nread << "\t" << maxsrcont << "\t" << totsrcont/AgSize << "\t" << totsrcont/(AgSize * (maxsrcont > 0.0 ? maxsrcont : 1.0)) << "\t" << accumulatedsrcont << endl; STATfile << nread << "\t" << maxsrcont << "\t" << totsrcont/AgSize << "\t"
<< totsrcont/(AgSize * (maxsrcont > 0.0 ? maxsrcont : 1.0)) << "\t" << accumulatedsrcont << endl;
naccounted = 0; naccounted = 0;
maxsrcont = 0.0; maxsrcont = 0.0;
totsrcont = 0.0; totsrcont = 0.0;

View File

@ -21,12 +21,10 @@ using namespace ABACUS;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc != 13 && argc != 14) { // Print out instructions 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 << "Usage of Smoothen_Heis_DSF executable: " << endl << endl;
cout << "Provide arguments using one of the following options:" << 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 << "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; cout << "2) (for fixed momentum) whichDSF Delta N M iKneeded ommin ommax Nom gwidth" << endl << endl;
//else ABACUSerror("Incomprehensible arguments in Smoothen_Heis_DSF executable.");
} }
else if (argc == 13) { // !fixed_iK else if (argc == 13) { // !fixed_iK
@ -84,7 +82,5 @@ int main(int argc, char* argv[])
} }
*/ */
//else ABACUSerror("Wrong number of arguments to Smoothen_Heis_DSF executable.");
return(0); return(0);
} }

View File

@ -25,13 +25,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl; cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl; cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << 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 << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
cout << "DP kBT \t\t Temperature" << 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 << "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 << "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 << "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 << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
@ -56,7 +58,6 @@ int main(int argc, char* argv[])
DP width = atof(argv[12]); DP width = atof(argv[12]);
stringstream filenameprefix; 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, "");
string prefix = filenameprefix.str(); string prefix = filenameprefix.str();
@ -65,15 +66,10 @@ int main(int argc, char* argv[])
Write_K_File (L, iKmin, iKmax); Write_K_File (L, iKmin, iKmax);
Write_Omega_File (Nom, ommin, ommax); 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:
// We use the scaled width function as default:
DP sumcheck; 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); 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;
} }
/* /*
@ -105,7 +101,5 @@ int main(int argc, char* argv[])
} }
*/ */
//else ABACUSerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
return(0); return(0);
} }

View File

@ -25,14 +25,16 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl; cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl; cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << 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 << "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 << "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; "
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; "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 << "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 << "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 << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
@ -51,7 +53,6 @@ int main(int argc, char* argv[])
char* Ix2filenameprefix = argv[n++]; char* Ix2filenameprefix = argv[n++];
int iKmin = atoi(argv[n++]); int iKmin = atoi(argv[n++]);
int iKmax = atoi(argv[n++]); int iKmax = atoi(argv[n++]);
//DP kBT = atof(argv[7]);
DP kBT = 0.0; DP kBT = 0.0;
int DiK = atoi(argv[n++]); int DiK = atoi(argv[n++]);
DP ommin = atof(argv[n++]); DP ommin = atof(argv[n++]);
@ -64,8 +65,6 @@ int main(int argc, char* argv[])
string defaultScanStatename = filenamestrstream.str(); string defaultScanStatename = filenamestrstream.str();
stringstream filenameprefix; 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); Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, defaultScanStatename);
string prefix = filenameprefix.str(); string prefix = filenameprefix.str();
@ -74,15 +73,10 @@ int main(int argc, char* argv[])
Write_K_File (L, iKmin, iKmax); Write_K_File (L, iKmin, iKmax);
Write_Omega_File (Nom, ommin, ommax); 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:
// We use the scaled width function as default:
DP sumcheck; 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); 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;
} }
/* /*
@ -114,7 +108,5 @@ int main(int argc, char* argv[])
} }
*/ */
//else ABACUSerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
return(0); return(0);
} }

View File

@ -25,7 +25,8 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Smoothen_LiebLin_DSF_MosesState executable: " << endl; cout << endl << "Usage of Smoothen_LiebLin_DSF_MosesState executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl; cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl; cout << "int N \t\t\t Number of particles" << endl;
@ -33,8 +34,8 @@ int main(int argc, char* argv[])
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << 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 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 << "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; "
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; "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 << "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 << "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 << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
@ -50,12 +51,10 @@ int main(int argc, char* argv[])
DP L = atof(argv[3]); DP L = atof(argv[3]);
int N = atoi(argv[4]); int N = atoi(argv[4]);
int Nl = atoi(argv[5]); int Nl = atoi(argv[5]);
//int Nr = N - Nl;
int DIl = atoi(argv[6]); int DIl = atoi(argv[6]);
int DIr = atoi(argv[7]); int DIr = atoi(argv[7]);
int iKmin = atoi(argv[8]); int iKmin = atoi(argv[8]);
int iKmax = atoi(argv[9]); int iKmax = atoi(argv[9]);
//DP kBT = atof(argv[10]);
DP kBT = 0.0; DP kBT = 0.0;
int DiK = atoi(argv[10]); int DiK = atoi(argv[10]);
DP ommin = atof(argv[11]); DP ommin = atof(argv[11]);
@ -69,7 +68,6 @@ int main(int argc, char* argv[])
string defaultScanStatename = defaultScanStatename_strstream.str(); string defaultScanStatename = defaultScanStatename_strstream.str();
stringstream filenameprefix; 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); Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, defaultScanStatename);
string prefix = filenameprefix.str(); string prefix = filenameprefix.str();
@ -80,18 +78,11 @@ int main(int argc, char* argv[])
Write_K_File (L, iKmin, iKmax); Write_K_File (L, iKmin, iKmax);
Write_Omega_File (Nom, ommin, ommax); 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: // We use the scaled width function as default:
DP sumcheck; 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); 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 ABACUSerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
return(0); return(0);
} }

View File

@ -25,13 +25,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Smoothen_LiebLin_DSF_Scaled executable: " << endl; cout << endl << "Usage of Smoothen_LiebLin_DSF_Scaled executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl; cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << 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 << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
cout << "DP kBT \t\t Temperature" << 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 << "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 << "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 << "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 << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
@ -56,27 +58,18 @@ int main(int argc, char* argv[])
DP width = atof(argv[12]); DP width = atof(argv[12]);
stringstream filenameprefix; 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, "");
string prefix = filenameprefix.str(); string prefix = filenameprefix.str();
DP normalization = twoPI * L; DP normalization = twoPI * L;
//DP denom_sum_K = L;
Write_K_File (L, iKmin, iKmax); Write_K_File (L, iKmin, iKmax);
Write_Omega_File (Nom, ommin, ommax); 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: // We use the scaled width function as default:
DP sumcheck; 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_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 ABACUSerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
return(0); return(0);
} }

View File

@ -25,18 +25,18 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl; cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Smoothen_LiebLin_DSF_over_Ensemble executable: " << endl; cout << endl << "Usage of Smoothen_LiebLin_DSF_over_Ensemble executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << 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 << "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 c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl; cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << 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 << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
cout << "DP kBT \t\t Temperature" << 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; "
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; "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 << "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 << "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 << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
cout << endl << "EXAMPLE: " << endl << 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; 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;
@ -50,7 +50,6 @@ int main(int argc, char* argv[])
int iKmin = atoi(argv[5]); int iKmin = atoi(argv[5]);
int iKmax = atoi(argv[6]); int iKmax = atoi(argv[6]);
DP kBT = atof(argv[7]); DP kBT = atof(argv[7]);
//int nstates_req = atoi(argv[8]);
int DiK = atoi(argv[8]); int DiK = atoi(argv[8]);
DP ommin = atof(argv[9]); DP ommin = atof(argv[9]);
DP ommax = atof(argv[10]); DP ommax = atof(argv[10]);
@ -58,7 +57,6 @@ int main(int argc, char* argv[])
DP width = atof(argv[12]); DP width = atof(argv[12]);
stringstream filenameprefix; 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, "");
string prefix = filenameprefix.str(); string prefix = filenameprefix.str();
@ -72,7 +70,6 @@ int main(int argc, char* argv[])
LiebLin_Diagonal_State_Ensemble ensemble; LiebLin_Diagonal_State_Ensemble ensemble;
stringstream ensfilestrstream; 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"; ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
string ensfilestr = ensfilestrstream.str(); string ensfilestr = ensfilestrstream.str();
const char* ensfile_Cstr = ensfilestr.c_str(); const char* ensfile_Cstr = ensfilestr.c_str();
@ -85,12 +82,10 @@ int main(int argc, char* argv[])
for (int ns = 0; ns < ensemble.nstates; ++ns) { for (int ns = 0; ns < ensemble.nstates; ++ns) {
// Define the raw input file name: // Define the raw input file name:
stringstream filenameprefix; 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); Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
string prefix = filenameprefix.str(); string prefix = filenameprefix.str();
stringstream RAW_stringstream; string RAW_string; stringstream RAW_stringstream; string RAW_string;
RAW_stringstream << prefix << ".raw"; RAW_stringstream << prefix << ".raw";
//RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
rawfilename[ns] = RAW_stringstream.str(); rawfilename[ns] = RAW_stringstream.str();
} }

View File

@ -21,12 +21,10 @@ using namespace ABACUS;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc != 10 && argc != 11) { // Print out instructions 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 << "Usage of Smoothen_ODSLF_DSF executable: " << endl << endl;
cout << "Provide arguments using one of the following options:" << 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 << "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; cout << "2) (for fixed momentum) whichDSF Delta N M iKneeded ommin ommax Nom gwidth" << endl << endl;
//else ABACUSerror("Incomprehensible arguments in Smoothen_ODSLF_DSF executable.");
} }
else if (argc == 11) { // !fixed_iK else if (argc == 11) { // !fixed_iK
@ -47,7 +45,8 @@ int main(int argc, char* argv[])
DP normalization = twoPI; DP normalization = twoPI;
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl; cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax,
Nom, gwidth, normalization) << endl;
Write_K_File (N, iKmin, iKmax); Write_K_File (N, iKmin, iKmax);
Write_Omega_File (Nom, ommin, ommax); Write_Omega_File (Nom, ommin, ommax);
@ -75,7 +74,8 @@ int main(int argc, char* argv[])
int iKmin = iKneeded; int iKmin = iKneeded;
int iKmax = iKneeded; int iKmax = iKneeded;
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl; cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax,
Nom, gwidth, normalization) << endl;
} }
else ABACUSerror("Wrong number of arguments to Smoothen_Heis_DSF executable."); else ABACUSerror("Wrong number of arguments to Smoothen_Heis_DSF executable.");

View File

@ -21,7 +21,8 @@ using namespace ABACUS;
int main( int argc, char* argv[]) int main( int argc, char* argv[])
{ {
if (!(argc == 3 || argc == 5)) { // provide some info 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 << 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 << "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 << "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; cout << "The output is Delta, N, stag mag, energy gap." << endl;
@ -57,7 +58,8 @@ int main( int argc, char* argv[])
if (!estate.conv) ABACUSerror("Umklapp state did not converge."); if (!estate.conv) ABACUSerror("Umklapp state did not converge.");
if (!estategap.conv) ABACUSerror("Gap state did not converge."); if (!estategap.conv) ABACUSerror("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; cout << Delta << "\t" << N << "\t" << setprecision(12) << exp(real(ln_Sz_ME (gstate, estate)))/sqrt(N)
<< "\t" << estategap.E - gstate.E << endl;
} }
@ -102,7 +104,8 @@ int main( int argc, char* argv[])
if (!estate.conv) ABACUSerror("Umklapp state did not converge."); if (!estate.conv) ABACUSerror("Umklapp state did not converge.");
if (!estategap.conv) ABACUSerror("Gap state did not converge."); if (!estategap.conv) ABACUSerror("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; cout << Delta << "\t" << N << "\t" << setprecision(12) << exp(real(ln_Sz_ME (gstate, estate)))/sqrt(N)
<< "\t" << estategap.E - gstate.E << endl;
} }
} }

View File

@ -27,8 +27,9 @@ namespace ABACUS {
si_n_anis_over_2(new DP[1]), co_n_anis_over_2(new DP[1]), ta_n_anis_over_2(new DP[1]), prec(ITER_REQ_PREC) {} si_n_anis_over_2(new DP[1]), co_n_anis_over_2(new DP[1]), ta_n_anis_over_2(new DP[1]), prec(ITER_REQ_PREC) {}
Heis_Chain::Heis_Chain (DP JJ, DP DD, DP hh, int NN) Heis_Chain::Heis_Chain (DP JJ, DP DD, DP hh, int NN)
: J(JJ), Delta(DD), anis(0.0), hz(hh), Nsites(NN), Nstrings(MAXSTRINGS), Str_L(new int[MAXSTRINGS]), par(new int[MAXSTRINGS]), : J(JJ), Delta(DD), anis(0.0), hz(hh), Nsites(NN), Nstrings(MAXSTRINGS), Str_L(new int[MAXSTRINGS]),
si_n_anis_over_2(new DP[10*MAXSTRINGS]), co_n_anis_over_2(new DP[10*MAXSTRINGS]), ta_n_anis_over_2(new DP[10*MAXSTRINGS]), prec(ITER_REQ_PREC) par(new int[MAXSTRINGS]), si_n_anis_over_2(new DP[10*MAXSTRINGS]), co_n_anis_over_2(new DP[10*MAXSTRINGS]),
ta_n_anis_over_2(new DP[10*MAXSTRINGS]), prec(ITER_REQ_PREC)
{ {
// We restrict to even chains everywhere // We restrict to even chains everywhere
@ -43,7 +44,6 @@ namespace ABACUS {
// Set the Str_L and par vectors: // Set the Str_L and par vectors:
DP gammaoverpi = acos(DD)/PI; DP gammaoverpi = acos(DD)/PI;
//cout << "gammaoverpi = " << gammaoverpi << endl;
Vect<int> Nu(MAXSTRINGS); Vect<int> Nu(MAXSTRINGS);
@ -67,15 +67,11 @@ namespace ABACUS {
for (int p = 0; p < l; ++p) gammaoverpi_reached = Nu[l - p - 1] + 1.0/gammaoverpi_reached; for (int p = 0; p < l; ++p) gammaoverpi_reached = Nu[l - p - 1] + 1.0/gammaoverpi_reached;
gammaoverpi_reached = 1.0/gammaoverpi_reached; gammaoverpi_reached = 1.0/gammaoverpi_reached;
//cout << "gammaoverpi_reached = " << gammaoverpi_reached << "\tdiff = " << fabs(gammaoverpi - gammaoverpi_reached) << endl;
//cout << "ml_temp = " << ml_temp << "\tMAXSTRINGS = " << MAXSTRINGS << endl;
l++; l++;
if (ml_temp > MAXSTRINGS) break; // we defined Str_L and par as arrays of at most MAXSTRINGS elements, so we cut off here... if (ml_temp > MAXSTRINGS) break; // we defined Str_L and par as arrays of at most MAXSTRINGS elements, so we cut off here...
} }
//cout << "l = " << l << endl;
// Check: make sure the last Nu is greater than one: if one, add 1 to previous Nu // Check: make sure the last Nu is greater than one: if one, add 1 to previous Nu
@ -253,86 +249,18 @@ namespace ABACUS {
if (ta_n_anis_over_2 != 0) delete[] ta_n_anis_over_2; if (ta_n_anis_over_2 != 0) delete[] ta_n_anis_over_2;
} }
/* Deactivated in ++G_8
void Heis_Chain::Scan_for_Possible_Bases (int Mdown_remaining, Vect<string>& possible_base_label, int& nfound, int nexc_max_used,
int base_level_to_scan, Vect<int>& Nrapidities)
{
if (Mdown_remaining < 0) { ABACUSerror("Scan_for_Possible_Bases: shouldn't be here..."); } // reached inconsistent point
//cout << "Mdown_remaining " << Mdown_remaining << "\t" << possible_base_id << "\tnfound " << nfound
// << "\tnexc_max_used " << nexc_max_used << "\tbase_level_to_scan " << base_level_to_scan << "\tNrap " << Nrapidities << endl;
if (base_level_to_scan == 0) {
Nrapidities[0] = Mdown_remaining;
// Set label:
stringstream M0out;
M0out << Nrapidities[0];
possible_base_label[nfound] = M0out.str();
for (int itype = 1; itype < Nrapidities.size(); ++itype)
if (Nrapidities[itype] > 0) {
possible_base_label[nfound] += TYPESEP;
stringstream typeout;
typeout << itype;
possible_base_label[nfound] += typeout.str();
possible_base_label[nfound] += EXCSEP;
stringstream Mout;
Mout << Nrapidities[itype];
possible_base_label[nfound] += Mout.str();
}
nfound++;
}
else {
// Remove all higher strings:
//Nrapidities[base_level_to_scan] = 0;
//Scan_for_Possible_Bases (Mdown_remaining, possible_base_id, nfound, nexc_max_used, base_level_to_scan - 1, Nrapidities);
for (int i = 0; i <= (Str_L[base_level_to_scan] == 0 ? 0 : nexc_max_used/Str_L[base_level_to_scan]); ++i) {
Nrapidities[base_level_to_scan] = i;
Scan_for_Possible_Bases (Mdown_remaining - i*Str_L[base_level_to_scan], possible_base_label, nfound,
nexc_max_used - i*Str_L[base_level_to_scan], base_level_to_scan - 1, Nrapidities);
}
}
}
Vect<string> Heis_Chain::Possible_Bases (int Mdown) // returns a vector of possible bases
{
// We partition Mdown into up to NEXC_MAX_HEIS excitations
int nexc_max_used = ABACUS::min(NEXC_MAX_HEIS, 2*(Mdown/2)); // since each inner sector can contain at most N/2 holes.
Vect<string> possible_base_label (1000);
int nfound = 0;
Vect<int> Nrapidities (0, Nstrings);
//cout << "In Possible_Bases: start scan for Mdown = " << Mdown << endl;
(*this).Scan_for_Possible_Bases (Mdown, possible_base_label, nfound, nexc_max_used, Nstrings - 1, Nrapidities);
// Copy results into a clean vector:
Vect<string> possible_base_label_found (nfound);
for (int i = 0; i < nfound; ++i) possible_base_label_found[i] = possible_base_label[i];
//cout << "In Possible_Bases: possible_base_label_found = " << possible_base_label_found << endl;
return(possible_base_label_found);
}
*/
//*************************************************************************************************** //***************************************************************************************************
// Function definitions: class Heis_Base // Function definitions: class Heis_Base
Heis_Base::Heis_Base () : Mdown(0), Nrap(Vect<int>()), Nraptot(0), Heis_Base::Heis_Base () : Mdown(0), Nrap(Vect<int>()), Nraptot(0), Ix2_infty(Vect<DP>()),
Ix2_infty(Vect<DP>()), Ix2_min(Vect<int>()), Ix2_max(Vect<int>()), dimH(0.0), baselabel("") {} Ix2_min(Vect<int>()), Ix2_max(Vect<int>()), dimH(0.0), baselabel("") {}
Heis_Base::Heis_Base (const Heis_Base& RefBase) // copy constructor Heis_Base::Heis_Base (const Heis_Base& RefBase) // copy constructor
: Mdown(RefBase.Mdown), Nrap(Vect<int>(RefBase.Nrap.size())), Nraptot(RefBase.Nraptot), : Mdown(RefBase.Mdown), Nrap(Vect<int>(RefBase.Nrap.size())), Nraptot(RefBase.Nraptot),
Ix2_infty(Vect<DP>(RefBase.Nrap.size())), Ix2_min(Vect<int>(RefBase.Nrap.size())), Ix2_max(Vect<int>(RefBase.Nrap.size())), Ix2_infty(Vect<DP>(RefBase.Nrap.size())), Ix2_min(Vect<int>(RefBase.Nrap.size())),
baselabel(RefBase.baselabel) Ix2_max(Vect<int>(RefBase.Nrap.size())), baselabel(RefBase.baselabel)
{ {
for (int i = 0; i < Nrap.size(); ++i) { for (int i = 0; i < Nrap.size(); ++i) {
Nrap[i] = RefBase.Nrap[i]; Nrap[i] = RefBase.Nrap[i];
@ -344,8 +272,8 @@ namespace ABACUS {
} }
Heis_Base::Heis_Base (const Heis_Chain& RefChain, int M) Heis_Base::Heis_Base (const Heis_Chain& RefChain, int M)
: Mdown(M), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), : Mdown(M), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)),
Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)) Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings))
{ {
for (int i = 0; i < RefChain.Nstrings; ++i) Nrap[i] = 0; for (int i = 0; i < RefChain.Nstrings; ++i) Nrap[i] = 0;
Nrap[0] = M; Nrap[0] = M;
@ -363,20 +291,21 @@ namespace ABACUS {
// Compute dimensionality of this sub-Hilbert space: // Compute dimensionality of this sub-Hilbert space:
complex<double> ln_dimH_cx = 0.0; complex<double> ln_dimH_cx = 0.0;
for (int i = 0; i < RefChain.Nstrings; ++i) for (int i = 0; i < RefChain.Nstrings; ++i)
if (Nrap[i] > 0) ln_dimH_cx += ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2)) - ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2 - Nrap[i])) - ln_Gamma(complex<double>(Nrap[i] + 1)); if (Nrap[i] > 0) ln_dimH_cx += ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2))
- ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2 - Nrap[i]))
- ln_Gamma(complex<double>(Nrap[i] + 1));
dimH = exp(real(ln_dimH_cx)); dimH = exp(real(ln_dimH_cx));
} }
Heis_Base::Heis_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities) Heis_Base::Heis_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities)
: Mdown(0), Nrap(Nrapidities), Nraptot(0), : Mdown(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)),
Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)) Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings))
{ {
// Check consistency of Nrapidities vector with RefChain // 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())
ABACUSerror("Incompatible Nrapidities vector used in Heis_Base constructor.");
if (RefChain.Nstrings != Nrapidities.size()) ABACUSerror("Incompatible Nrapidities vector used in Heis_Base constructor.");
int Mcheck = 0; int Mcheck = 0;
for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i]; for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
@ -385,33 +314,6 @@ namespace ABACUS {
Nraptot = 0; Nraptot = 0;
for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i]; 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;
}
*/
// Set label:
/*
stringstream baselabel_strstream;
baselabel_strstream << Nrapidities[0];
for (int itype = 1; itype < Nrapidities.size(); ++itype)
if (Nrapidities[itype] > 0) {
baselabel_strstream << TYPESEP;
stringstream typeout;
typeout << itype;
baselabel += typeout.str();
baselabel += 'EXCSEP';
stringstream Mout;
Mout << Nrapidities[itype];
baselabel += Mout.str();
}
*/
stringstream M0out; stringstream M0out;
M0out << Nrapidities[0]; M0out << Nrapidities[0];
baselabel = M0out.str(); baselabel = M0out.str();
@ -433,14 +335,15 @@ namespace ABACUS {
// Compute dimensionality of this sub-Hilbert space: // Compute dimensionality of this sub-Hilbert space:
complex<double> ln_dimH_cx = 0.0; complex<double> ln_dimH_cx = 0.0;
for (int i = 0; i < RefChain.Nstrings; ++i) for (int i = 0; i < RefChain.Nstrings; ++i)
if (Nrap[i] > 0) ln_dimH_cx += ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2)) - ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2 - Nrap[i])) - ln_Gamma(complex<double>(Nrap[i] + 1)); if (Nrap[i] > 0) ln_dimH_cx += ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2))
- ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2 - Nrap[i]))
- ln_Gamma(complex<double>(Nrap[i] + 1));
dimH = exp(real(ln_dimH_cx)); dimH = exp(real(ln_dimH_cx));
} }
Heis_Base::Heis_Base (const Heis_Chain& RefChain, string baselabel_ref) Heis_Base::Heis_Base (const Heis_Chain& RefChain, string baselabel_ref)
: Mdown(0), Nrap(Vect<int>(0, RefChain.Nstrings)), Nraptot(0), : Mdown(0), Nrap(Vect<int>(0, RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)),
Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)), Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)), baselabel (baselabel_ref)
baselabel (baselabel_ref)
{ {
// Build Nrapidities vector from baselabel_ref. // Build Nrapidities vector from baselabel_ref.
// This is simply done by using the state label standard reading function after conveniently // This is simply done by using the state label standard reading function after conveniently
@ -448,10 +351,8 @@ namespace ABACUS {
string label_ref = baselabel + "_0_"; string label_ref = baselabel + "_0_";
Vect<Vect<int> > dummyOriginIx2(1); Vect<Vect<int> > dummyOriginIx2(1);
//cout << "Trying to build base from baselabel_ref " << baselabel_ref << "\t and label_ref " << label_ref << endl;
//State_Label_Data labeldata = Read_State_Label (label_ref, dummyOriginIx2); //State_Label_Data labeldata = Read_State_Label (label_ref, dummyOriginIx2);
State_Label_Data labeldata = Read_Base_Label (label_ref); State_Label_Data labeldata = Read_Base_Label (label_ref);
//cout << "Read data." << endl;
// Initialize Nrap: // Initialize Nrap:
for (int i = 0; i < labeldata.type.size(); ++i) for (int i = 0; i < labeldata.type.size(); ++i)
@ -470,7 +371,9 @@ namespace ABACUS {
// Compute dimensionality of this sub-Hilbert space: // Compute dimensionality of this sub-Hilbert space:
complex<double> ln_dimH_cx = 0.0; complex<double> ln_dimH_cx = 0.0;
for (int i = 0; i < RefChain.Nstrings; ++i) for (int i = 0; i < RefChain.Nstrings; ++i)
if (Nrap[i] > 0) ln_dimH_cx += ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2)) - ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2 - Nrap[i])) - ln_Gamma(complex<double>(Nrap[i] + 1)); if (Nrap[i] > 0) ln_dimH_cx += ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2))
- ln_Gamma(complex<double>((Ix2_max[i] - Ix2_min[i])/2 + 2 - Nrap[i]))
- ln_Gamma(complex<double>(Nrap[i] + 1));
dimH = exp(real(ln_dimH_cx)); dimH = exp(real(ln_dimH_cx));
} }
@ -521,8 +424,9 @@ namespace ABACUS {
sum2 = 0.0; 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]) sum2 += (RefChain.Str_L[j] == RefChain.Str_L[k]) ? 0.0 :
- 0.5 * fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) * RefChain.anis)); 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]) 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)); - 0.5 * (RefChain.Str_L[j] + RefChain.Str_L[k]) * RefChain.anis));
@ -533,8 +437,9 @@ namespace ABACUS {
sum1 += (Nrap[k] - ((j == k) ? 1 : 0)) * sum2; 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]) Ix2_infty[j] = (1.0/PI) * fabs(RefChain.Nsites *
- 0.5 * RefChain.Str_L[j] * RefChain.anis)) - sum1); 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. } // The Ix2_infty are now set.
@ -576,7 +481,6 @@ namespace ABACUS {
sum1 += Nrap[k] * (2 * ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0)); sum1 += Nrap[k] * (2 * ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0));
} }
//Ix2_infty[j] = (RefChain.Nsites - 1.0 + 2.0 * RefChain.Str_L[j] - sum1);
Ix2_infty[j] = (RefChain.Nsites + 1.0 - sum1); // to get counting right... Ix2_infty[j] = (RefChain.Nsites + 1.0 - sum1); // to get counting right...
} // The Ix2_infty are now set. } // The Ix2_infty are now set.
@ -644,10 +548,6 @@ namespace ABACUS {
Ix2_max[j] -= 2; Ix2_max[j] -= 2;
} }
// Fudge, for strings:
//if (RefChain.Str_L[j] >= 1) Ix2_max[j] += 2;
//Ix2_max[j] += 2;
Ix2_min[j] = -Ix2_max[j]; Ix2_min[j] = -Ix2_max[j];
} }
@ -665,22 +565,17 @@ namespace ABACUS {
Lambda::Lambda (const Heis_Chain& RefChain, int M) Lambda::Lambda (const Heis_Chain& RefChain, int M)
: Nstrings(1), Nrap(Vect<int>(M,1)), Nraptot(M), lambda(new DP*[1]) // single type of string here : Nstrings(1), Nrap(Vect<int>(M,1)), Nraptot(M), lambda(new DP*[1]) // single type of string here
//: lambda(Vect<Vect<DP> > (1))
{ {
lambda[0] = new DP[M]; lambda[0] = new DP[M];
//lambda[0] = Vect<DP> (M);
for (int j = 0; j < M; ++j) lambda[0][j] = 0.0; for (int j = 0; j < M; ++j) lambda[0][j] = 0.0;
} }
Lambda::Lambda (const Heis_Chain& RefChain, const Heis_Base& base) Lambda::Lambda (const Heis_Chain& RefChain, const Heis_Base& base)
: Nstrings(RefChain.Nstrings), Nrap(base.Nrap), Nraptot(base.Nraptot), lambda(new DP*[RefChain.Nstrings]) : Nstrings(RefChain.Nstrings), Nrap(base.Nrap), Nraptot(base.Nraptot), lambda(new DP*[RefChain.Nstrings])
//: lambda(Vect<Vect<DP> > (RefChain.Nstrings))
{ {
//lambda[0] = new DP[base.Mdown];
lambda[0] = new DP[base.Nraptot]; lambda[0] = new DP[base.Nraptot];
for (int i = 1; i < RefChain.Nstrings; ++i) lambda[i] = lambda[i-1] + base[i-1]; for (int i = 1; i < RefChain.Nstrings; ++i) lambda[i] = lambda[i-1] + base[i-1];
//for (int i = 0; i < RefChain.Nstrings; ++i) lambda[i] = Vect<DP> (base[i]);
for (int i = 0; i < RefChain.Nstrings; ++i) { for (int i = 0; i < RefChain.Nstrings; ++i) {
for (int j = 0; j < base[i]; ++j) lambda[i][j] = 0.0; for (int j = 0; j < base[i]; ++j) lambda[i][j] = 0.0;
@ -704,7 +599,7 @@ namespace ABACUS {
for (int i = 0; i < Nstrings; ++i) for (int i = 0; i < Nstrings; ++i)
for (int j = 0; j < Nrap[i]; ++j) lambda[i][j] = RefLambda.lambda[i][j]; for (int j = 0; j < Nrap[i]; ++j) lambda[i][j] = RefLambda.lambda[i][j];
} }
return(*this); return(*this);
} }
@ -722,56 +617,33 @@ namespace ABACUS {
// Function definitions: class Heis_Bethe_State // Function definitions: class Heis_Bethe_State
Heis_Bethe_State::Heis_Bethe_State () Heis_Bethe_State::Heis_Bethe_State ()
: chain(Heis_Chain()), base(Heis_Base()), //offsets(Ix2_Offsets()), : chain(Heis_Chain()), base(Heis_Base()), Ix2(Vect<Vect<int> > (1)),
//Ix2(Ix2_Config(chain, 1)),
Ix2(Vect<Vect<int> > (1)),
lambda(Lambda(chain, 1)), BE(Lambda(chain, 1)), diffsq(0.0), conv(0), dev(1.0), iter(0), iter_Newton(0), lambda(Lambda(chain, 1)), BE(Lambda(chain, 1)), diffsq(0.0), conv(0), dev(1.0), iter(0), iter_Newton(0),
E(0.0), iK(0), K(0.0), lnnorm(-100.0), //base_id(0LL), type_id(0LL), id(0LL), maxid(0LL), nparticles(0) E(0.0), iK(0), K(0.0), lnnorm(-100.0), label("")
label("")
{ {
}; };
Heis_Bethe_State::Heis_Bethe_State (const Heis_Bethe_State& RefState) // copy constructor Heis_Bethe_State::Heis_Bethe_State (const Heis_Bethe_State& RefState) // copy constructor
//: chain(RefState.chain), base(RefState.base), offsets(RefState.offsets), Ix2(Ix2_Config(RefState.chain, RefState.base.Mdown)), : chain(RefState.chain), base(RefState.base), Ix2(RefState.Ix2),
// lambda(Lambda(RefState.chain, RefState.base.Mdown)), BE(Lambda(RefState.chain, RefState.base.Mdown)),
: chain(RefState.chain), base(RefState.base), //offsets(RefState.offsets),
//Ix2(Ix2_Config(RefState.chain, RefState.base)),
Ix2 (RefState.Ix2),
lambda(Lambda(RefState.chain, RefState.base)), BE(Lambda(RefState.chain, RefState.base)), lambda(Lambda(RefState.chain, RefState.base)), BE(Lambda(RefState.chain, RefState.base)),
diffsq(RefState.diffsq), conv(RefState.conv), dev(RefState.dev), iter(RefState.iter), iter_Newton(RefState.iter_Newton), diffsq(RefState.diffsq), conv(RefState.conv), dev(RefState.dev),
iter(RefState.iter), iter_Newton(RefState.iter_Newton),
E(RefState.E), iK(RefState.iK), K(RefState.K), lnnorm(RefState.lnnorm), E(RefState.E), iK(RefState.iK), K(RefState.K), lnnorm(RefState.lnnorm),
//id(RefState.id), maxid(RefState.maxid)
//base_id(RefState.base_id), type_id(RefState.type_id), id(RefState.id), maxid(RefState.maxid), nparticles(RefState.nparticles)
label(RefState.label) label(RefState.label)
{ {
// copy arrays into new ones // copy arrays into new ones
/*
cout << "Here in Heis constructor state" << endl;
cout << "lambda " << lambda[0][0] << endl;
cout << "lambda OK" << endl;
cout << "RefConfig: " << endl << RefState.Ix2 << endl;
cout << "(*this).Ix2: " << endl << Ix2 << endl;
*/
for (int j = 0; j < RefState.chain.Nstrings; ++j) { for (int j = 0; j < RefState.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < RefState.base[j]; ++j) { for (int alpha = 0; alpha < RefState.base[j]; ++j) {
//Ix2[j][alpha] = RefState.Ix2[j][alpha]; // not needed anymore since Ix2 is Vect<Vect<int> >
lambda[j][alpha] = RefState.lambda[j][alpha]; lambda[j][alpha] = RefState.lambda[j][alpha];
} }
} }
//cout << "Heis constructor state OK" << endl;
} }
Heis_Bethe_State::Heis_Bethe_State (const Heis_Chain& RefChain, int M) Heis_Bethe_State::Heis_Bethe_State (const Heis_Chain& RefChain, int M)
: chain(RefChain), base(RefChain, M), //offsets(base, 0LL), : chain(RefChain), base(RefChain, M), Ix2(Vect<Vect<int> > (1)),
//Ix2(Ix2_Config(RefChain, M)),
Ix2 (Vect<Vect<int> > (1)),
lambda(Lambda(RefChain, M)), lambda(Lambda(RefChain, M)),
BE(Lambda(RefChain, M)), diffsq(1.0), conv(0), dev(1.0), iter(0), iter_Newton(0), BE(Lambda(RefChain, M)), diffsq(1.0), conv(0), dev(1.0), iter(0), iter_Newton(0),
E(0.0), iK(0), K(0.0), lnnorm(-100.0) E(0.0), iK(0), K(0.0), lnnorm(-100.0)
//id(0LL), maxid(0LL)
//base_id(0LL), type_id(0LL), id(0LL), maxid(offsets.maxid), nparticles(0)
{ {
Ix2[0] = Vect<int> (M); Ix2[0] = Vect<int> (M);
for (int j = 0; j < M; ++j) Ix2[0][j] = -(M - 1) + 2*j; for (int j = 0; j < M; ++j) Ix2[0][j] = -(M - 1) + 2*j;
@ -782,20 +654,12 @@ namespace ABACUS {
} }
Heis_Bethe_State::Heis_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase) Heis_Bethe_State::Heis_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase)
: chain(RefChain), base(RefBase), //offsets(RefBase, 0LL), : chain(RefChain), base(RefBase), Ix2 (Vect<Vect<int> > (RefChain.Nstrings)),
//Ix2(Ix2_Config(RefChain, RefBase)),
Ix2 (Vect<Vect<int> > (RefChain.Nstrings)),
lambda(Lambda(RefChain, RefBase)), lambda(Lambda(RefChain, RefBase)),
BE(Lambda(RefChain, RefBase)), diffsq(1.0), conv(0), dev(1.0), iter(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0) BE(Lambda(RefChain, RefBase)), diffsq(1.0), conv(0), dev(1.0),
//id(0LL), maxid(0LL) iter(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0)
//base_id(RefBase.id), type_id(0LL), id(0LL), maxid(offsets.maxid), nparticles(0)
{ {
// Check that the number of rapidities is consistent with Mdown // Check that the number of rapidities is consistent with Mdown
//cout << "Here in Heis constructor chain base" << endl;
//cout << "lambda " << lambda[0][0] << endl;
//cout << "lambda OK" << endl;
int Mcheck = 0; int Mcheck = 0;
for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += base[i] * RefChain.Str_L[i]; for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += base[i] * RefChain.Str_L[i];
if (RefBase.Mdown != Mcheck) ABACUSerror("Wrong M from Nrapidities input vector, in Heis_Bethe_State constructor."); if (RefBase.Mdown != Mcheck) ABACUSerror("Wrong M from Nrapidities input vector, in Heis_Bethe_State constructor.");
@ -812,15 +676,8 @@ namespace ABACUS {
void Heis_Bethe_State::Set_to_Label (string label_ref, const Vect<Vect<int> >& OriginIx2) void Heis_Bethe_State::Set_to_Label (string label_ref, const Vect<Vect<int> >& OriginIx2)
{ {
//cout << "Called Set_to_Label with label_ref " << label_ref << " on state " << (*this) << endl;
//cout << "Check labeldata of label " << label_ref << endl;
State_Label_Data labeldata = Read_State_Label (label_ref, OriginIx2); State_Label_Data labeldata = Read_State_Label (label_ref, OriginIx2);
//cout << "type: " << labeldata.type << endl << "M: " << labeldata.M << endl << "nexc: " << labeldata.nexc << endl;
//for (int i = 0; i < labeldata.Ix2old.size(); ++i) cout << "Ix2old[" << i << "] = " << labeldata.Ix2old[i] << endl << "Ix2exc[" << i << "] = " << labeldata.Ix2exc[i] << endl;
label = label_ref; label = label_ref;
Vect<Vect<int> > OriginIx2ordered = OriginIx2; Vect<Vect<int> > OriginIx2ordered = OriginIx2;
@ -835,26 +692,11 @@ namespace ABACUS {
for (int iexc = 0; iexc < labeldata.nexc[it]; ++iexc) for (int iexc = 0; iexc < labeldata.nexc[it]; ++iexc)
for (int i = 0; i < labeldata.M[it]; ++i) for (int i = 0; i < labeldata.M[it]; ++i)
if (Ix2[labeldata.type[it] ][i] == labeldata.Ix2old[it][iexc]) { if (Ix2[labeldata.type[it] ][i] == labeldata.Ix2old[it][iexc]) {
//cout << it << "\t" << iexc << "\t" << i << endl;
//cout << "\tSetting Ix2[" << labeldata.type[it] << "][" << i << "] to " << labeldata.Ix2exc[it][iexc] << endl;
//cout << Ix2[labeldata.type[it] ][i] << "\t" << labeldata.Ix2old[it][iexc] << "\t" << labeldata.Ix2exc[it][iexc] << endl;
Ix2[labeldata.type[it] ][i] = labeldata.Ix2exc[it][iexc]; Ix2[labeldata.type[it] ][i] = labeldata.Ix2exc[it][iexc];
//cout << Ix2[labeldata.type[it] ][i] << "\t" << labeldata.Ix2old[it][iexc] << "\t" << labeldata.Ix2exc[it][iexc] << endl;
} }
//cout << "State obtained(1): " << (*this) << endl;
// Now reorder the Ix2 to follow convention: // Now reorder the Ix2 to follow convention:
for (int il = 0; il < Ix2.size(); ++il) Ix2[il].QuickSort(); for (int il = 0; il < Ix2.size(); ++il) Ix2[il].QuickSort();
//cout << "Setting label:" << label_ref << endl << "Ix2old = " << labeldata.Ix2old[0] << endl << "Ix2exc = " << labeldata.Ix2exc[0] << endl;
//cout << "on " << OriginStateIx2ordered << endl << "giving " << Ix2 << endl;
//cout << "State obtained(2): " << (*this) << endl;
//char a; cin >> a;
//(*this).Set_Label_from_Ix2 (OriginStateIx2ordered);
//(*this).Set_Label_Internals_from_Ix2 (OriginStateIx2ordered);
} }
void Heis_Bethe_State::Set_Label_from_Ix2 (const Vect<Vect<int> >& OriginIx2) void Heis_Bethe_State::Set_Label_from_Ix2 (const Vect<Vect<int> >& OriginIx2)
@ -865,11 +707,13 @@ namespace ABACUS {
// (*this) has a base already identical to base of OriginIx2 // (*this) has a base already identical to base of OriginIx2
// First check that bases are consistent // First check that bases are consistent
if ((*this).chain.Nstrings != OriginIx2.size()) ABACUSerror("Inconsistent base sizes in Heis_Bethe_State::Set_Label_from_Ix2."); if ((*this).chain.Nstrings != OriginIx2.size())
ABACUSerror("Inconsistent base sizes in Heis_Bethe_State::Set_Label_from_Ix2.");
// Then check that the filling at each level is equal // Then check that the filling at each level is equal
for (int il = 0; il < (*this).chain.Nstrings; ++il) for (int il = 0; il < (*this).chain.Nstrings; ++il)
if ((*this).base.Nrap[il] != OriginIx2[il].size()) ABACUSerror("Inconsistent base filling in Heis_Bethe_State::Set_Label_from_Ix2."); if ((*this).base.Nrap[il] != OriginIx2[il].size())
ABACUSerror("Inconsistent base filling in Heis_Bethe_State::Set_Label_from_Ix2.");
// Determine how many types of particles are present // Determine how many types of particles are present
int ntypes = 1; // level 0 always assumed present int ntypes = 1; // level 0 always assumed present
@ -891,7 +735,6 @@ namespace ABACUS {
Vect<Vect<int> > Ix2exc_ref(ntypes); Vect<Vect<int> > Ix2exc_ref(ntypes);
// Count nr of particle-holes at each level: // Count nr of particle-holes at each level:
//itype = 0;
itype = -1; itype = -1;
for (int il = 0; il < chain.Nstrings; ++il) { for (int il = 0; il < chain.Nstrings; ++il) {
if (il == 0 || base.Nrap[il] > 0) { if (il == 0 || base.Nrap[il] > 0) {
@ -932,36 +775,16 @@ namespace ABACUS {
bool symmetric_state = true; bool symmetric_state = true;
int arg, test1, test3; int arg, test1, test3;
//if (chain.Delta <= 1.0) { for (int j = 0; j < chain.Nstrings; ++j) {
test1 = 0;
for (int j = 0; j < chain.Nstrings; ++j) { test3 = 0;
test1 = 0; for (int alpha = 0; alpha < base[j]; ++alpha) {
test3 = 0; arg = (Ix2[j][alpha] != chain.Nsites) ? Ix2[j][alpha] : 0; // since Ix2 = N is same as Ix2 = -N by periodicity, this is symmetric.
for (int alpha = 0; alpha < base[j]; ++alpha) { test1 += arg;
arg = (Ix2[j][alpha] != chain.Nsites) ? Ix2[j][alpha] : 0; // since Ix2 = N is same as Ix2 = -N by periodicity, this is symmetric. test3 += arg * arg * arg; // to make sure that all I's are symmetrical...
test1 += arg;
test3 += arg * arg * arg; // to make sure that all I's are symmetrical...
}
if (!(symmetric_state && (test1 == 0) && (test3 == 0))) symmetric_state = false;
}
//}
/*
else if (chain.Delta > 1.0) {
// For the gapped antiferromagnet, we check symmetry *excluding* the Ix2_max values
// The state is then inadmissible is symmetric && -Ix2_max occupied
for (int j = 0; j < chain.Nstrings; ++j) {
test1 = 0;
test3 = 0;
for (int alpha = 0; alpha < base[j]; ++alpha) {
arg = (Ix2[j][alpha] != chain.Nsites
&& abs(Ix2[j][alpha]) != base.Ix2_max[j]) ? Ix2[j][alpha] : 0; // since Ix2 = N is same as Ix2 = -N by periodicity, this is symmetric.
test1 += arg;
test3 += arg * arg * arg; // to make sure that all I's are symmetrical...
}
if (!(symmetric_state && (test1 == 0) && (test3 == 0))) symmetric_state = false;
} }
if (!(symmetric_state && (test1 == 0) && (test3 == 0))) symmetric_state = false;
} }
*/
return symmetric_state; return symmetric_state;
} }
@ -991,8 +814,6 @@ namespace ABACUS {
{ {
// This function finds the rapidities of the eigenstate // This function finds the rapidities of the eigenstate
//cout << endl << "Find_Rapidities called: " << (*this) << endl;
lnnorm = -100.0; // sentinel value, recalculated if Newton method used in the last step of iteration. lnnorm = -100.0; // sentinel value, recalculated if Newton method used in the last step of iteration.
Lambda lambda_ref(chain, base); Lambda lambda_ref(chain, base);
@ -1001,10 +822,7 @@ namespace ABACUS {
if (reset_rapidities) if (reset_rapidities)
(*this).Set_Free_lambdas(); (*this).Set_Free_lambdas();
//cout << endl << "After Set_Free_lambdas: " << (*this) << endl;
(*this).Compute_BE(); (*this).Compute_BE();
//cout << endl << "After Compute_BE: " << (*this) << endl;
iter = 0; iter = 0;
iter_Newton = 0; iter_Newton = 0;
@ -1037,7 +855,6 @@ namespace ABACUS {
|| straight_improving || extrap_improving || Newton_improving)) { || straight_improving || extrap_improving || Newton_improving)) {
// If we haven't reset, first try a few Newton steps... // If we haven't reset, first try a few Newton steps...
//if (!reset_rapidities && iter_Newton == 0) (*this).Solve_BAE_Newton (chain.prec, 10);
if (!Newton_improving) diffsq_iter_aim *= 1.0e-5; if (!Newton_improving) diffsq_iter_aim *= 1.0e-5;
@ -1060,9 +877,9 @@ namespace ABACUS {
iter_prec = diffsq * 0.1; iter_prec = diffsq * 0.1;
if (info_findrap) cout << "Straight iter: iter " << iter << "\titer_factor " << iter_factor << "\tdiffsq " << diffsq << endl; if (info_findrap) cout << "Straight iter: iter " << iter << "\titer_factor " << iter_factor
<< "\tdiffsq " << diffsq << endl;
//} while (diffsq > chain.prec && !is_nan(diffsq) && diffsq_extrap_stop/diffsq_extrap_start < 0.01);
} while (diffsq > diffsq_iter_aim && !is_nan(diffsq) && diffsq_extrap_stop/diffsq_extrap_start < 0.01); } while (diffsq > diffsq_iter_aim && !is_nan(diffsq) && diffsq_extrap_stop/diffsq_extrap_start < 0.01);
straight_improving = (diffsq < diffsq_start); straight_improving = (diffsq < diffsq_start);
@ -1115,10 +932,6 @@ namespace ABACUS {
Newton_improving = (diffsq < diffsq_Newton_start); Newton_improving = (diffsq < diffsq_Newton_start);
//if (diffsq > iter_prec) (*this).Solve_BAE_smackdown (0.1 * diffsq, 1);
//cout << "Before silk: diffsq = " << diffsq << endl;
// If none of the methods are improving the result, try the silk gloves... // If none of the methods are improving the result, try the silk gloves...
if (!(straight_improving || extrap_improving || Newton_improving)) { if (!(straight_improving || extrap_improving || Newton_improving)) {
if (info_findrap) cout << "Before silk gloves: diffsq " << diffsq << endl; if (info_findrap) cout << "Before silk gloves: diffsq " << diffsq << endl;
@ -1138,14 +951,9 @@ namespace ABACUS {
// Check convergence: // Check convergence:
//cout << "Check_Rapidities: " << (*this).Check_Rapidities() << endl;
//conv = (diffsq < chain.prec && (*this).Check_Rapidities() && ((*this).String_delta() < HEIS_deltaprec)) ? 1 : 0;
conv = (diffsq < chain.prec && (*this).Check_Rapidities()) ? 1 : 0; conv = (diffsq < chain.prec && (*this).Check_Rapidities()) ? 1 : 0;
dev = (*this).String_delta(); dev = (*this).String_delta();
//cout << "String delta: " << (*this).String_delta() << "\tBoolean: " << ((*this).String_delta() < HEIS_deltaprec) << endl;
return; return;
} }
@ -1167,7 +975,6 @@ namespace ABACUS {
DP BEleft, BEmid, BEright; DP BEleft, BEmid, BEright;
lambda[j][alpha] = lambdaleft; lambda[j][alpha] = lambdaleft;
(*this).Compute_BE (j, alpha); (*this).Compute_BE (j, alpha);
//cout << "lambda: " << lambda[j][alpha] << "\ttanhlambda: " << tanh(lambda[j][alpha]) << endl;
BEleft= BE[j][alpha]; BEleft= BE[j][alpha];
lambda[j][alpha] = lambdaright; lambda[j][alpha] = lambdaright;
(*this).Compute_BE (j, alpha); (*this).Compute_BE (j, alpha);
@ -1175,8 +982,6 @@ namespace ABACUS {
if (BEleft * BEright > 0.0) { if (BEleft * BEright > 0.0) {
lambda[j][alpha] = lambdajalphastart; lambda[j][alpha] = lambdajalphastart;
//cout << lambdaleft << "\t" << lambdaright << "\t" << BEleft << "\t" << BEright << endl;
//cout << "Could not bisect BE[" << j << "][" << alpha << "]" << endl;
return; return;
} }
@ -1187,9 +992,6 @@ namespace ABACUS {
(*this).Compute_BE (j, alpha); (*this).Compute_BE (j, alpha);
BEmid = BE[j][alpha]; BEmid = BE[j][alpha];
//cout << "niter_here = " << niter_here << "\t" << lambdaleft << "\t" << lambdamid << "\t" << lambdaright << endl;
//cout << BEleft << "\t" << BEmid << "\t" << BEright << endl;
if (BEmid * BEleft < 0.0) { // root is to the left of mid if (BEmid * BEleft < 0.0) { // root is to the left of mid
lambdaright = lambdamid; lambdaright = lambdamid;
BEright = BEmid; BEright = BEmid;
@ -1203,16 +1005,12 @@ namespace ABACUS {
else if (BEmid * BEmid < req_prec) return; else if (BEmid * BEmid < req_prec) return;
else { else {
//cout << lambdaleft << "\t" << lambdamid << "\t" << lambdaright << endl;
//cout << BEleft << "\t" << BEmid << "\t" << BEright << endl;
//ABACUSerror("Problem in Solve_BAE_bisect.");
return; // this procedure has failed return; // this procedure has failed
} }
prec_obtained = BEmid * BEmid; prec_obtained = BEmid * BEmid;
niter_here++; niter_here++;
//cout << "bisect: " << lambdaleft << "\t" << lambdaright << "\t" << BEleft << "\t" << BEright << "\t" << prec_obtained << "\t" << req_prec << endl;
} }
return; return;
@ -1220,15 +1018,10 @@ namespace ABACUS {
void Heis_Bethe_State::Iterate_BAE (DP iter_factor) void Heis_Bethe_State::Iterate_BAE (DP iter_factor)
{ {
//DP lambda_old;
for (int j = 0; j < chain.Nstrings; ++j) { for (int j = 0; j < chain.Nstrings; ++j) {
for (int alpha = 0; alpha < base[j]; ++alpha) for (int alpha = 0; alpha < base[j]; ++alpha)
{ {
//lambda_old = lambda[j][alpha];
//lambda[j][alpha] = Iterate_BAE (j, alpha);
lambda[j][alpha] += iter_factor * (Iterate_BAE (j, alpha) - lambda[j][alpha]); lambda[j][alpha] += iter_factor * (Iterate_BAE (j, alpha) - lambda[j][alpha]);
//cout << j << "\t" << alpha << "\t" << Ix2[j][alpha] << "\t" << lambda_old << "\t" << lambda[j][alpha] << "\t";
//if (j > 0) cout << j << "\t" << alpha << "\t" << Ix2[j][alpha] << "\t" << lambda_old << "\t" << lambda[j][alpha] << endl;
} }
} }
@ -1247,7 +1040,8 @@ namespace ABACUS {
Lambda lambda_ref(chain, base); Lambda lambda_ref(chain, base);
DP diffsq_ref = 1.0; DP diffsq_ref = 1.0;
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha];
diffsq_ref = diffsq; diffsq_ref = diffsq;
// Now begin solving... // Now begin solving...
@ -1257,16 +1051,14 @@ namespace ABACUS {
while ((diffsq > straight_prec) && (max_iter > iter_done_here)) { while ((diffsq > straight_prec) && (max_iter > iter_done_here)) {
//cout << "BEFORE ITERATION" << endl << (*this) << endl << endl;
(*this).Iterate_BAE(iter_factor); (*this).Iterate_BAE(iter_factor);
//cout << "ITERATION " << iter_done_here << endl << (*this) << endl << endl;
iter_done_here++; iter_done_here++;
} }
if ((diffsq > diffsq_ref) || (is_nan(diffsq))) { if ((diffsq > diffsq_ref) || (is_nan(diffsq))) {
// This procedure has failed. We reset everything to begin values. // This procedure has failed. We reset everything to begin values.
//cout << "Straight iter failed: resetting." << endl; for (int j = 0; j < chain.Nstrings; ++j)
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha]; for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha];
(*this).Compute_BE(); (*this).Compute_BE();
diffsq = diffsq_ref; diffsq = diffsq_ref;
} }
@ -1281,7 +1073,8 @@ namespace ABACUS {
Lambda lambda_ref(chain, base); Lambda lambda_ref(chain, base);
DP diffsq_ref = 1.0; DP diffsq_ref = 1.0;
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha];
diffsq_ref = diffsq; diffsq_ref = diffsq;
// Now begin solving... // Now begin solving...
@ -1300,20 +1093,21 @@ namespace ABACUS {
while ((diffsq > extrap_prec) && (max_iter_extrap > iter_done_here)) { while ((diffsq > extrap_prec) && (max_iter_extrap > iter_done_here)) {
(*this).Iterate_BAE(iter_factor); (*this).Iterate_BAE(iter_factor);
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda1[j][alpha] = lambda[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) lambda1[j][alpha] = lambda[j][alpha];
diffsq1 = diffsq; diffsq1 = diffsq;
(*this).Iterate_BAE(iter_factor); (*this).Iterate_BAE(iter_factor);
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda2[j][alpha] = lambda[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) lambda2[j][alpha] = lambda[j][alpha];
diffsq2 = diffsq; diffsq2 = diffsq;
(*this).Iterate_BAE(iter_factor); (*this).Iterate_BAE(iter_factor);
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda3[j][alpha] = lambda[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) lambda3[j][alpha] = lambda[j][alpha];
diffsq3 = diffsq; diffsq3 = diffsq;
(*this).Iterate_BAE(iter_factor); (*this).Iterate_BAE(iter_factor);
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda4[j][alpha] = lambda[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) lambda4[j][alpha] = lambda[j][alpha];
diffsq4 = diffsq; diffsq4 = diffsq;
//(*this).Iterate_BAE(iter_factor);
//for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda5[j][alpha] = lambda[j][alpha];
//diffsq5 = diffsq;
iter_done_here += 4; iter_done_here += 4;
@ -1332,11 +1126,8 @@ namespace ABACUS {
rap[1] = lambda2[j][alpha]; rap[1] = lambda2[j][alpha];
rap[2] = lambda3[j][alpha]; rap[2] = lambda3[j][alpha];
rap[3] = lambda4[j][alpha]; rap[3] = lambda4[j][alpha];
//rap[4] = lambda5[j][alpha];
polint (oneoverP, rap, 0.0, lambda[j][alpha], deltalambda); polint (oneoverP, rap, 0.0, lambda[j][alpha], deltalambda);
//cout << j << "\t" << alpha << "\t" << rap << "\t" << lambda[j][alpha] << "\t" << deltalambda << endl;
} }
// Iterate once to stabilize result // Iterate once to stabilize result
@ -1347,7 +1138,8 @@ namespace ABACUS {
if ((diffsq >= diffsq_ref) || (is_nan(diffsq))) { if ((diffsq >= diffsq_ref) || (is_nan(diffsq))) {
// This procedure has failed. We reset everything to begin values. // This procedure has failed. We reset everything to begin values.
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha];
(*this).Compute_BE(); (*this).Compute_BE();
diffsq = diffsq_ref; diffsq = diffsq_ref;
} }
@ -1365,7 +1157,8 @@ namespace ABACUS {
Lambda lambda_ref(chain, base); Lambda lambda_ref(chain, base);
DP diffsq_ref = 1.0; DP diffsq_ref = 1.0;
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha];
diffsq_ref = diffsq; diffsq_ref = diffsq;
// Now begin solving... // Now begin solving...
@ -1389,35 +1182,13 @@ namespace ABACUS {
} }
} }
//cout << "jmax = " << jmax << "\talphamax = " << alphamax << "\t" << lambda[jmax][alphamax] << "\tBE before " << BE[jmax][alphamax] << endl;
// Now recalculate this max deviant rapidity,
//cout << lambda[jmax][alphamax] << "\t" << Iterate_BAE (jmax, alphamax) << endl;
/*
DP dlambda = 0.0;
DP prevBEmax = 0.0;
do {
dlambda = Iterate_BAE (jmax, alphamax) - lambda[jmax][alphamax];
lambda[jmax][alphamax] += iter_factor * dlambda;
prevBEmax = BE[jmax][alphamax];
(*this).Compute_BE();
iter_done_here++;
cout << "jmax = " << jmax << "\talphamax = " << alphamax << "\t" << lambda[jmax][alphamax] << "\t" << dlambda << "\tBE during " << BE[jmax][alphamax] << endl;
} while (dlambda * dlambda > silk_prec && fabs(BE[jmax][alphamax]) < fabs(prevBEmax) && max_iter_silk > iter_done_here);
*/
Solve_BAE_bisect (jmax, alphamax, silk_prec, max_iter_silk); Solve_BAE_bisect (jmax, alphamax, silk_prec, max_iter_silk);
iter_done_here++; iter_done_here++;
//cout << "jmax = " << jmax << "\talphamax = " << alphamax << "\t" << lambda[jmax][alphamax] << "\tBE after " << BE[jmax][alphamax] << endl;
// and reset all important arrays. // and reset all important arrays.
(*this).Compute_diffsq(); (*this).Compute_diffsq();
} }
//cout << "Silk gloves: diffsq from " << diffsq_ref << "\tto " << diffsq << endl;
if ((diffsq > diffsq_ref) || (is_nan(diffsq))) { if ((diffsq > diffsq_ref) || (is_nan(diffsq))) {
// This procedure has failed. We reset everything to begin values. // This procedure has failed. We reset everything to begin values.
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha];
@ -1428,32 +1199,6 @@ namespace ABACUS {
return; return;
} }
/*
void Heis_Bethe_State::BAE_smackdown (DP max_allowed)
{
// Re-solves for all rapidities lambda[j][alpha] such that BE[j][alpha]^2/N > max_allowed.
// Assumes that BE[][] is up-to-date.
for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha)
if (pow(BE[j][alpha], 2.0)/chain.Nsites > max_allowed) (*this).Solve_BAE (j, alpha, max_allowed, 100);
}
void Heis_Bethe_State::Solve_BAE_smackdown (DP max_allowed, int maxruns)
{
int runs_done = 0;
(*this).Compute_BE();
(*this).Compute_diffsq();
while (diffsq > chain.prec && diffsq > max_allowed && runs_done < maxruns) {
(*this).BAE_smackdown (max_allowed);
(*this).Compute_BE();
(*this).Compute_diffsq();
runs_done++;
}
}
*/
void Heis_Bethe_State::Iterate_BAE_Newton () void Heis_Bethe_State::Iterate_BAE_Newton ()
{ {
@ -1465,7 +1210,8 @@ namespace ABACUS {
Vect_INT indx (base.Nraptot); Vect_INT indx (base.Nraptot);
Lambda lambda_ref(chain, base); Lambda lambda_ref(chain, base);
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha];
(*this).Build_Reduced_Gaudin_Matrix (Gaudin); (*this).Build_Reduced_Gaudin_Matrix (Gaudin);
@ -1488,16 +1234,14 @@ namespace ABACUS {
return; return;
} }
//cout << iter_Newton << "\t" << dlambda << endl;
// Regularize dlambda: max step is +-1.0 to prevent rapidity flying off into outer space. // Regularize dlambda: max step is +-1.0 to prevent rapidity flying off into outer space.
for (int i = 0; i < base.Nraptot; ++i) if (fabs(real(dlambda[i])) > 1.0) dlambda[i] = 0.0;//(real(dlambda[i]) > 0) ? 1.0 : -1.0; for (int i = 0; i < base.Nraptot; ++i)
if (fabs(real(dlambda[i])) > 1.0) dlambda[i] = 0.0;//(real(dlambda[i]) > 0) ? 1.0 : -1.0;
index = 0; index = 0;
for (int j = 0; j < chain.Nstrings; ++j) for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) { for (int alpha = 0; alpha < base[j]; ++alpha) {
lambda[j][alpha] = lambda_ref[j][alpha] + real(dlambda[index]); lambda[j][alpha] = lambda_ref[j][alpha] + real(dlambda[index]);
//cout << j << "\t" << alpha << "\t" << dlambda[index] << "\t" << lambda_ref[j][alpha] << "\t" << lambda[j][alpha] << endl;
index++; index++;
} }
@ -1521,12 +1265,14 @@ namespace ABACUS {
{ {
// This function attempts to get convergence diffsq <= Newton_prec in at most max_iter_Newton steps. // This function attempts to get convergence diffsq <= Newton_prec in at most max_iter_Newton steps.
// The results are accepted if diffsq has decreased, otherwise the lambda's are reset to original values, defined as... // The results are accepted if diffsq has decreased,
// otherwise the lambda's are reset to original values, defined as...
Lambda lambda_ref(chain, base); Lambda lambda_ref(chain, base);
DP diffsq_ref = 1.0; DP diffsq_ref = 1.0;
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha]; for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) lambda_ref[j][alpha] = lambda[j][alpha];
diffsq_ref = diffsq; diffsq_ref = diffsq;
// Now begin solving... // Now begin solving...
@ -1541,8 +1287,8 @@ namespace ABACUS {
if ((diffsq > diffsq_ref) || (is_nan(diffsq))) { if ((diffsq > diffsq_ref) || (is_nan(diffsq))) {
// This procedure has failed. We reset everything to begin values. // This procedure has failed. We reset everything to begin values.
//cout << "Newton: failed, resetting." << "\t" << diffsq << endl; for (int j = 0; j < chain.Nstrings; ++j)
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha]; for (int alpha = 0; alpha < base[j]; ++alpha) lambda[j][alpha] = lambda_ref[j][alpha];
(*this).Compute_BE(); (*this).Compute_BE();
diffsq = diffsq_ref; diffsq = diffsq_ref;
} }
@ -1558,19 +1304,8 @@ namespace ABACUS {
SQMat_CX Gaudin_Red(base.Nraptot); SQMat_CX Gaudin_Red(base.Nraptot);
(*this).Build_Reduced_Gaudin_Matrix(Gaudin_Red); (*this).Build_Reduced_Gaudin_Matrix(Gaudin_Red);
/*
cout << endl << "Gaudin matrix: " << endl;
for (int j = 0; j < Gaudin_Red.size(); ++j) {
for (int k = 0; k < Gaudin_Red.size(); ++k) cout << Gaudin_Red[j][k] << " ";
cout << endl;
}
cout << endl << endl;
*/
complex<DP> lnnorm_check = lndet_LU_CX_dstry(Gaudin_Red); complex<DP> lnnorm_check = lndet_LU_CX_dstry(Gaudin_Red);
//cout << "Calculated lnnorm = " << lnnorm_check;
//lnnorm = real(lndet_LU_CX_dstry(Gaudin_Red));
lnnorm = real(lnnorm_check); lnnorm = real(lnnorm_check);
} }
@ -1613,37 +1348,15 @@ namespace ABACUS {
return; return;
} }
/*
bool Heis_Bethe_State::Boost_Momentum (int iKboost)
{
if (iKboost == 0) return(true); // done
Ix2_Offsets offsets_here = offsets;
bool success = false;
if (iKboost < 0)
success = offsets_here.Add_Boxes_From_Lowest(-iKboost, 0); // add boxes in even sectors to decrease iK
else if (iKboost > 0)
success = offsets_here.Add_Boxes_From_Lowest(iKboost, 1); // add boxes in odd sectors to increase iK
if (success) (*this).Set_Ix2_Offsets(offsets_here);
return(success);
}
*/
void Heis_Bethe_State::Set_to_Closest_Matching_Ix2_fixed_Base (const Heis_Bethe_State& StateToMatch) void Heis_Bethe_State::Set_to_Closest_Matching_Ix2_fixed_Base (const Heis_Bethe_State& StateToMatch)
{ {
// Given a state with given Ix2 distribution, set the Ix2 to closest match. // Given a state with given Ix2 distribution, set the Ix2 to closest match.
// The base of (*this) is fixed, and does not necessarily match that of StateToMatch. // The base of (*this) is fixed, and does not necessarily match that of StateToMatch.
//cout << "Matching Ix2 for base " << (*this).base.baselabel << " from base " << StateToMatch.base.baselabel << endl;
if ((*this).chain != StateToMatch.chain) if ((*this).chain != StateToMatch.chain)
ABACUSerror("Heis_Bethe_State::Find_Closest_Matching_Ix2_fixed_Base: trying to match Ix2 for two states with different chains."); ABACUSerror("Heis_Bethe_State::Find_Closest_Matching_Ix2_fixed_Base: "
"trying to match Ix2 for two states with different chains.");
// Check level by level, match quantum numbers from center up. // Check level by level, match quantum numbers from center up.
for (int il = 0; il < chain.Nstrings; ++il) { for (int il = 0; il < chain.Nstrings; ++il) {
@ -1663,15 +1376,16 @@ namespace ABACUS {
(*this).Ix2[il][a] = -(*this).base.Nrap[il] + 1 + 2*a; (*this).Ix2[il][a] = -(*this).base.Nrap[il] + 1 + 2*a;
int nleft = StateToMatch.base.Nrap[il]/2; int nleft = StateToMatch.base.Nrap[il]/2;
for (int a = 0; a < nleft; ++a) for (int a = 0; a < nleft; ++a)
if (StateToMatch.Ix2[il][a] - Ix2shift < (*this).Ix2[il][a]) (*this).Ix2[il][a] = StateToMatch.Ix2[il][a] - Ix2shift; if (StateToMatch.Ix2[il][a] - Ix2shift < (*this).Ix2[il][a])
(*this).Ix2[il][a] = StateToMatch.Ix2[il][a] - Ix2shift;
for (int a = 0; a < StateToMatch.base.Nrap[il] - 1 - nleft; ++a) for (int a = 0; a < StateToMatch.base.Nrap[il] - 1 - nleft; ++a)
if (StateToMatch.Ix2[il][StateToMatch.base.Nrap[il] - 1 - a] - Ix2shift > (*this).Ix2[il][(*this).base.Nrap[il] - 1 - a]) if (StateToMatch.Ix2[il][StateToMatch.base.Nrap[il] - 1 - a] - Ix2shift
(*this).Ix2[il][(*this).base.Nrap[il] - 1 - a] = StateToMatch.Ix2[il][StateToMatch.base.Nrap[il] - 1 - a] - Ix2shift; > (*this).Ix2[il][(*this).base.Nrap[il] - 1 - a])
(*this).Ix2[il][(*this).base.Nrap[il] - 1 - a] = (StateToMatch.Ix2[il][StateToMatch.base.Nrap[il] - 1 - a]
- Ix2shift);
} }
} // for il } // for il
//cout << "StateToMatch:" << endl << StateToMatch << endl << "MatchingState:" << endl << (*this) << endl;
} }
@ -1679,16 +1393,19 @@ namespace ABACUS {
{ {
// sends all the state data to output stream // sends all the state data to output stream
s << endl << "******** Chain with Delta = " << state.chain.Delta << " Nsites = " << state.chain.Nsites << " Mdown = " << state.base.Mdown s << endl << "******** Chain with Delta = " << state.chain.Delta
//<< ": eigenstate with base_id " << state.base_id << ", type_id " << state.type_id << " id " << state.id << " maxid " << state.maxid << endl << " Nsites = " << state.chain.Nsites << " Mdown = " << state.base.Mdown
<< ": eigenstate with label " << state.label << endl << ": eigenstate with label " << state.label << endl
<< "E = " << state.E << " K = " << state.K << " iK = " << state.iK << " lnnorm = " << state.lnnorm << endl << "E = " << state.E << " K = " << state.K << " iK = " << state.iK << " lnnorm = " << state.lnnorm << endl
<< "conv = " << state.conv << " dev = " << state.dev << " iter = " << state.iter << " iter_Newton = " << state.iter_Newton << "\tdiffsq " << state.diffsq << endl; << "conv = " << state.conv << " dev = " << state.dev << " iter = " << state.iter
<< " iter_Newton = " << state.iter_Newton << "\tdiffsq " << state.diffsq << endl;
for (int j = 0; j < state.chain.Nstrings; ++j) { for (int j = 0; j < state.chain.Nstrings; ++j) {
if (state.base.Nrap[j] > 0) { if (state.base.Nrap[j] > 0) {
s << "Type " << j << " Str_L = " << state.chain.Str_L[j] << " par = " << state.chain.par[j] << " M_j = " << state.base.Nrap[j] s << "Type " << j << " Str_L = " << state.chain.Str_L[j] << " par = " << state.chain.par[j]
<< " Ix2_infty = " << state.base.Ix2_infty[j] << " Ix2_min = " << state.base.Ix2_min[j] << " Ix2_max = " << state.base.Ix2_max[j] << endl; << " M_j = " << state.base.Nrap[j]
<< " Ix2_infty = " << state.base.Ix2_infty[j] << " Ix2_min = " << state.base.Ix2_min[j]
<< " Ix2_max = " << state.base.Ix2_max[j] << endl;
Vect_INT qnumbers(state.base.Nrap[j]); Vect_INT qnumbers(state.base.Nrap[j]);
Vect_DP rapidities(state.base.Nrap[j]); Vect_DP rapidities(state.base.Nrap[j]);
for (int alpha = 0; alpha < state.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < state.base.Nrap[j]; ++alpha) {

View File

@ -125,19 +125,16 @@ namespace ABACUS {
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero); HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
M_found = (HZmin_actual < HZ && HZ <= HZmax_actual); 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); return(M_actual);
} }
DP Chemical_Potential (const Heis_Bethe_State& AveragingState) 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 return(-H_vs_M (AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown));
// - sign since E_{M+1} - E_M = -H
} }
} }

View File

@ -19,10 +19,6 @@ using namespace ABACUS;
namespace ABACUS { namespace ABACUS {
//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, 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) XXZ_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
{ {
@ -43,7 +39,6 @@ namespace ABACUS {
ME = exp(real(ln_Smin_ME (RightState, LeftState))); ME = exp(real(ln_Smin_ME (RightState, LeftState)));
else if (whichDSF == 'z') { else if (whichDSF == 'z') {
if (LeftState.label == RightState.label) 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); 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 ME = exp(real(ln_Sz_ME (RightState, LeftState)));
} }
@ -53,8 +48,6 @@ namespace ABACUS {
if (is_nan(ME)) ME = 0.0; 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: // Do the momentum business:
int iKout = LeftState.iK - RightState.iK; int iKout = LeftState.iK - RightState.iK;
while(iKout < 0) iKout += RightState.chain.Nsites; while(iKout < 0) iKout += RightState.chain.Nsites;
@ -64,17 +57,17 @@ namespace ABACUS {
// Print information to fstream: // Print information to fstream:
if (iKout >= iKmin && iKout <= iKmax) { if (iKout >= iKmin && iKout <= iKmax) {
if (whichDSF == 'Z') { if (whichDSF == 'Z') {
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" DAT_outfile << endl << setprecision(16)
<< LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
<< iKout << "\t" << iKout << "\t"
//<< LeftState.conv << "\t"
<< setprecision(3) << LeftState.dev << "\t" << setprecision(3) << LeftState.dev << "\t"
<< LeftState.label; << LeftState.label;
} }
else { else {
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" DAT_outfile << endl << setprecision(16)
<< LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
<< iKout << "\t" << iKout << "\t"
<< ME << "\t" << ME << "\t"
//<< LeftState.conv << "\t"
<< setprecision(3) << LeftState.dev << "\t" << setprecision(3) << LeftState.dev << "\t"
<< LeftState.label; << LeftState.label;
} }
@ -82,7 +75,6 @@ namespace ABACUS {
// Calculate and return the data_value: // Calculate and return the data_value:
DP data_value = ME * ME; DP data_value = ME * ME;
//DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
if (whichDSF == 'Z') // use 1/(1 + omega) 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); data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
@ -92,10 +84,7 @@ namespace ABACUS {
return(data_value); 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, 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) XXX_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
{ {
@ -120,30 +109,35 @@ namespace ABACUS {
ME = exp(real(ln_Smin_ME (RightState, LeftState))); ME = exp(real(ln_Smin_ME (RightState, LeftState)));
else if (whichDSF == 'z') { else if (whichDSF == 'z') {
// Recognize the presence of an infinite rapidity: // 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: if (LeftState.base.Mdown == RightState.base.Mdown - 1) {
// infinite rapidity present, use rescaled S^- matrix element instead of S^z one:
nrinfrap = 1; nrinfrap = 1;
// Correction factor for MEsq: Smffsq to Szffsq = 1/(N - 2M + 2) // 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))); 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: else { // no infinite rapidity, use S^z matrix element:
if (LeftState.label == RightState.label) 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); 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 ME = exp(real(ln_Sz_ME (RightState, LeftState)));
} }
} }
else if (whichDSF == 'p') { else if (whichDSF == 'p') {
// Recognize the presence of two infinite rapidities: // 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^+ if (LeftState.base.Mdown == RightState.base.Mdown - 1) {
// two infinite rapidities, use rescaled S^- matrix element instead of S^+
nrinfrap = 2; nrinfrap = 2;
// Correction factor for MEsq: Smffsq to Spffsq = 2/((N - 2M + 2) (N - 2M + 1)) // 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))) 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))); * 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^+ else if (LeftState.base.Mdown == RightState.base.Mdown) {
// one infinite rapidity, use rescaled S^z matrix element instead of S^+
nrinfrap = 1; nrinfrap = 1;
// Correction factor for MEsq: Szffsq to Spffsq = 4/(N - 2M) // 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))); 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 ME = exp(real(ln_Smin_ME (LeftState, RightState)));
} }
@ -154,17 +148,12 @@ namespace ABACUS {
else if (whichDSF == 'c') // S^-_j S^-{j+1} operator else if (whichDSF == 'c') // S^-_j S^-{j+1} operator
ME = exp(real(ln_Smm_ME (RightState, LeftState))); ME = exp(real(ln_Smm_ME (RightState, LeftState)));
else if (whichDSF == 'q') // Geometric quench else if (whichDSF == 'q') // Geometric quench
//ME_CX = ln_Overlap (LeftState, RightState);
ME_CX = ln_Overlap (RightState, LeftState); ME_CX = ln_Overlap (RightState, LeftState);
else ABACUSerror("Wrong whichDSF in Compute_Matrix_Element_Contrib."); else ABACUSerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
if (is_nan(ME)) ME = 0.0; if (is_nan(ME)) ME = 0.0;
if (is_nan(norm(ME_CX))) ME_CX = -100.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: // Do the momentum business:
int iKout = LeftState.iK - RightState.iK; int iKout = LeftState.iK - RightState.iK;
while(iKout < 0) iKout += RightState.chain.Nsites; while(iKout < 0) iKout += RightState.chain.Nsites;
@ -174,26 +163,26 @@ namespace ABACUS {
// Print information to fstream: // Print information to fstream:
if (iKout >= iKmin && iKout <= iKmax) { if (iKout >= iKmin && iKout <= iKmax) {
if (whichDSF == 'Z') { if (whichDSF == 'Z') {
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t" DAT_outfile << endl << setprecision(16)
<< iKout << "\t" << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot
//<< LeftState.conv << "\t" << "\t" << iKout << "\t"
<< setprecision(3) << LeftState.dev << "\t" << setprecision(3) << LeftState.dev << "\t"
<< LeftState.label; << LeftState.label;
} }
else if (whichDSF == 'q') { else if (whichDSF == 'q') {
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t" DAT_outfile << endl << setprecision(16)
<< iKout << "\t" << 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" << 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" << setprecision(3) << LeftState.dev << "\t"
<< LeftState.label; << LeftState.label;
} }
else { else {
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t" DAT_outfile << endl << setprecision(16)
<< iKout << "\t" << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot
<< "\t" << iKout << "\t"
<< ME << "\t" << ME << "\t"
//<< LeftState.conv << "\t"
<< setprecision(3) << LeftState.dev << "\t" << setprecision(3) << LeftState.dev << "\t"
<< LeftState.label; << LeftState.label;
} }
@ -201,7 +190,6 @@ namespace ABACUS {
// Calculate and return the data_value: // Calculate and return the data_value:
DP data_value = ME * ME; DP data_value = ME * ME;
//DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
if (whichDSF == 'Z') // use 1/(1 + omega) 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); data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
else if (whichDSF == 'q') else if (whichDSF == 'q')
@ -212,10 +200,7 @@ namespace ABACUS {
return(data_value); 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, 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) XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
{ {
@ -223,16 +208,6 @@ namespace ABACUS {
// and returns a weighed `data_value' to be multiplied by sumrule_factor, // and returns a weighed `data_value' to be multiplied by sumrule_factor,
// to determine if scanning along this thread should be continued. // 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); bool fixed_iK = (iKmin == iKmax);
@ -240,52 +215,6 @@ namespace ABACUS {
bool rap_in_fundamental = true; bool rap_in_fundamental = true;
int sum1 = 0; int sum1 = 0;
for (int j = 0; j < LeftState.chain.Nstrings; ++j) { 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 * ABACUS::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) // Logic: allow rapidities -PI/2 <= lambda <= PI/2 (including boundaries)
if (LeftState.base.Nrap[j] > 0 && if (LeftState.base.Nrap[j] > 0 &&
@ -308,7 +237,6 @@ namespace ABACUS {
// Identify which matrix element is needed from the number of particles in Left and Right states: // Identify which matrix element is needed from the number of particles in Left and Right states:
DP ME = 0.0; DP ME = 0.0;
//if (!(LeftState.conv && RightState.conv)) ME = 0.0;
if (!(LeftState.conv && RightState.conv && rap_in_fundamental)) ME = 0.0; if (!(LeftState.conv && RightState.conv && rap_in_fundamental)) ME = 0.0;
else if (whichDSF == 'Z') else if (whichDSF == 'Z')
@ -317,7 +245,6 @@ namespace ABACUS {
ME = exp(real(ln_Smin_ME (RightState, LeftState))); ME = exp(real(ln_Smin_ME (RightState, LeftState)));
else if (whichDSF == 'z') { else if (whichDSF == 'z') {
if (LeftState.label == RightState.label) 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); 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 ME = exp(real(ln_Sz_ME (RightState, LeftState)));
} }
@ -327,7 +254,6 @@ namespace ABACUS {
if (is_nan(ME)) ME = 0.0; 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; if (fabs(ME) > 1.0) ME = 0.0;
// Do the momentum business: // Do the momentum business:
@ -339,33 +265,24 @@ namespace ABACUS {
// Print information to fstream: // Print information to fstream:
if (iKout >= iKmin && iKout <= iKmax) { if (iKout >= iKmin && iKout <= iKmax) {
if (whichDSF == 'Z') { if (whichDSF == 'Z') {
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" DAT_outfile << endl << setprecision(16)
<< LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
<< iKout << "\t" << iKout << "\t"
//<< LeftState.conv << "\t"
<< setprecision(3) << LeftState.dev << "\t" << setprecision(3) << LeftState.dev << "\t"
<< LeftState.label; << LeftState.label;
} }
else { else {
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" DAT_outfile << endl << setprecision(16)
<< LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
<< iKout << "\t" << iKout << "\t"
<< ME << "\t" << ME << "\t"
//<< LeftState.conv << "\t"
<< setprecision(3) << LeftState.dev << "\t" << setprecision(3) << LeftState.dev << "\t"
<< LeftState.label; << 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 } // if iKmin <= iKout <= iKmax
// Calculate and return the data_value: // Calculate and return the data_value:
DP data_value = ME * ME; DP data_value = ME * ME;
//DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
if (whichDSF == 'Z') // use 1/(1 + omega) 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); 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: else if (fixed_iK) // data value is MEsq * omega:

View File

@ -99,7 +99,6 @@ namespace ABACUS {
else ABACUSerror("Wrong anisotropy in S1_sumrule_factor."); else ABACUSerror("Wrong anisotropy in S1_sumrule_factor.");
DP answer = 0.0; 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); 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: // Careful for z ! Hamiltonian defined as S^z S^z - 1/4, so add back N/4:
@ -118,8 +117,9 @@ namespace ABACUS {
DP sumrule = 0.0; 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')
//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; 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;
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 = iK == 0 ? 1.0 : -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
@ -130,20 +130,16 @@ namespace ABACUS {
else ABACUSerror("option not implemented in S1_sumrule_factor."); else ABACUSerror("option not implemented in S1_sumrule_factor.");
//return(1.0/sumrule); return(1.0/(sumrule + 1.0e-32)); // sumrule is 0 for iK == 0 or N
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 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; 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')
//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; 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;
else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N; else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
@ -154,15 +150,13 @@ namespace ABACUS {
else ABACUSerror("option not implemented in S1_sumrule_factor."); else ABACUSerror("option not implemented in S1_sumrule_factor.");
return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N return(1.0/(sumrule + 1.0e-32)); // 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 (char whichDSF, Heis_Bethe_State& AveragingState, DP Chem_Pot, int iKmin, int iKmax)
{ {
DP sumrule_factor = 1.0; DP sumrule_factor = 1.0;
//if (!fixed_iK) {
if (iKmin != iKmax) { if (iKmin != iKmax) {
if (whichDSF == 'Z') sumrule_factor = 1.0; if (whichDSF == 'Z') sumrule_factor = 1.0;
else if (whichDSF == 'm') else if (whichDSF == 'm')
@ -176,12 +170,11 @@ namespace ABACUS {
else ABACUSerror("whichDSF option not consistent in Sumrule_Factor"); else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
} }
//else if (fixed_iK) {
else if (iKmin == iKmax) { else if (iKmin == iKmax) {
if (whichDSF == 'Z') sumrule_factor = 1.0; if (whichDSF == 'Z') sumrule_factor = 1.0;
else if (whichDSF == 'm' || whichDSF == 'z' || whichDSF == 'p') 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,
sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, Chem_Pot, iKmax); AveragingState.base.Mdown, Chem_Pot, iKmax);
else if (whichDSF == 'a') sumrule_factor = 1.0; else if (whichDSF == 'a') sumrule_factor = 1.0;
else if (whichDSF == 'b') sumrule_factor = 1.0; else if (whichDSF == 'b') sumrule_factor = 1.0;
else if (whichDSF == 'c') sumrule_factor = 1.0; else if (whichDSF == 'c') sumrule_factor = 1.0;
@ -190,13 +183,12 @@ namespace ABACUS {
else ABACUSerror("whichDSF option not consistent in Sumrule_Factor"); else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
} }
return(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) 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; stringstream RAW_stringstream; string RAW_string;
@ -216,18 +208,15 @@ namespace ABACUS {
int iKmod = AveragingState.chain.Nsites; int iKmod = AveragingState.chain.Nsites;
// We run through the data file to chech the f sumrule at each positive momenta: // 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); Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);
DP omega, ME; DP omega, ME;
int iK, iKexc; int iK, iKexc;
//int conv;
DP dev; DP dev;
string label; string label;
while (infile.peek() != EOF) { while (infile.peek() != EOF) {
infile >> omega >> iK >> ME >> dev >> label; infile >> omega >> iK >> ME >> dev >> label;
//if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
iKexc = iK; iKexc = iK;
while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod; while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod; while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
@ -245,7 +234,9 @@ namespace ABACUS {
for (int i = iKmin; i <= iKmax; ++i) { for (int i = iKmin; i <= iKmax; ++i) {
if (i > iKmin) outfile << endl; 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 << 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(); outfile.close();

View File

@ -126,11 +126,8 @@ namespace ABACUS {
M_found = (HZmin_actual < HZ && HZ <= HZmax_actual); 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); return(M_actual);
} }

View File

@ -53,22 +53,12 @@ namespace ABACUS {
ABACUSerror("Delta != 1.0 in XXX_Bethe_State constructor"); ABACUSerror("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;
ABACUSerror("Delta != 1.0 in XXX_Bethe_State constructor");
}
}
*/
XXX_Bethe_State& XXX_Bethe_State::operator= (const XXX_Bethe_State& RefState) XXX_Bethe_State& XXX_Bethe_State::operator= (const XXX_Bethe_State& RefState)
{ {
if (this != &RefState) { if (this != &RefState) {
chain = RefState.chain; chain = RefState.chain;
base = RefState.base; base = RefState.base;
//offsets = RefState.offsets;
Ix2 = RefState.Ix2; Ix2 = RefState.Ix2;
lambda = RefState.lambda; lambda = RefState.lambda;
BE = RefState.BE; BE = RefState.BE;
@ -80,11 +70,6 @@ namespace ABACUS {
iK = RefState.iK; iK = RefState.iK;
K = RefState.K; K = RefState.K;
lnnorm = RefState.lnnorm; 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; label = RefState.label;
} }
return(*this); return(*this);
@ -115,15 +100,15 @@ namespace ABACUS {
// and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE. // and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE.
bool answer = true; bool answer = true;
//int test1, test3;
Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
bool higher_string_on_zero = false; bool higher_string_on_zero = false;
for (int j = 0; j < chain.Nstrings; ++j) { 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 // 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)) for (int alpha = 0; alpha < base[j]; ++alpha)
higher_string_on_zero = true; 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; 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. // NOTE: if base[j] == 0, Zero_at_level[j] remains false.
} }
@ -137,18 +122,13 @@ namespace ABACUS {
if (Zero_at_level[j1] && Zero_at_level[j2] && (!((chain.Str_L[j1] + chain.Str_L[j2])%2))) if (Zero_at_level[j1] && Zero_at_level[j2] && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
string_coincidence = true; 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*/)); 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) // 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 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; for (int alpha = 0; alpha < base[j]; ++alpha)
if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
if (!answer) { if (!answer) {
E = 0.0; E = 0.0;
@ -211,123 +191,9 @@ namespace ABACUS {
{ {
// Returns a new iteration value for lambda[j][alpha] given BE[j][alpha] // Returns a new iteration value for lambda[j][alpha] given BE[j][alpha]
return(0.5 * chain.Str_L[j] * tan(0.5 * return(0.5 * chain.Str_L[j] * tan(0.5 * (2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - BE[j][alpha])));
//(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 XXX_Bethe_State::Check_Rapidities()
{ {
bool nonan = true; bool nonan = true;
@ -345,9 +211,8 @@ namespace ABACUS {
DP delta = 0.0; DP delta = 0.0;
int occupied_strings = 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]; 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; if (occupied_strings == 0) delta = 0.0;
@ -367,8 +232,9 @@ namespace ABACUS {
if ((*this).chain.Str_L[j] > 1) { // else the BAE are already 1 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)) log_BAE_reg = DP((*this).chain.Nsites)
/((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0))); * 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 k = 0; k < (*this).chain.Nstrings; ++k)
for (int beta = 0; beta < (*this).base[k]; ++beta) for (int beta = 0; beta < (*this).base[k]; ++beta)
@ -376,15 +242,14 @@ namespace ABACUS {
if ((j != k) || (alpha != beta) || (a != b - 1)) 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 ) 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 ) - ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
) - II ); ) - II );
if ((j != k) || (alpha != beta) || (a != b + 1)) 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 ) 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))
- ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ) + II );
) + II );
} }
// The regular LHS of BAE is now defined. Now sum up the deltas... // The regular LHS of BAE is now defined. Now sum up the deltas...
@ -432,37 +297,11 @@ namespace ABACUS {
return; 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) void XXX_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
{ {
if (Gaudin_Red.size() != base.Nraptot) ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix."); if (Gaudin_Red.size() != base.Nraptot)
ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
int index_jalpha; int index_jalpha;
int index_kbeta; int index_kbeta;
@ -489,8 +328,8 @@ namespace ABACUS {
} }
Gaudin_Red[index_jalpha][index_kbeta] 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]) = complex<DP> ( chain.Nsites * chain.Str_L[j]/(lambda[j][alpha] * lambda[j][alpha]
- sum_hbar_XXX); + 0.25 * chain.Str_L[j] * chain.Str_L[j]) - sum_hbar_XXX);
} }
else { else {
@ -553,25 +392,12 @@ namespace ABACUS {
DP result = (nj == nk) ? 0.0 : DP(n)/(lambda * lambda + 0.25 * n * n); DP result = (nj == nk) ? 0.0 : DP(n)/(lambda * lambda + 0.25 * n * n);
for (int a = 1; a < ABACUS::min(nj, nk); ++a) result += 2.0 * (n + 2.0*a) for (int a = 1; a < ABACUS::min(nj, nk); ++a) result += 2.0 * (n + 2.0*a)
/ (lambda * lambda + 0.25 * (n + 2.0*a) * (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)); result += DP(nj + nk)/(lambda * lambda + 0.25 * (nj + nk) * (nj + nk));
return (result); 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 < ABACUS::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) XXX_Bethe_State Add_Particle_at_Center (const XXX_Bethe_State& RefState)
{ {
@ -593,7 +419,8 @@ namespace ABACUS {
// and shift quantum numbers by half-integer away from added one: // 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; 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) 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); ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)]
= RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
return(ReturnState); return(ReturnState);
} }
@ -617,10 +444,11 @@ namespace ABACUS {
// Remove midmost and shift quantum numbers by half-integer towards removed one: // Remove midmost and shift quantum numbers by half-integer towards removed one:
for (int i = 0; i < RefState.base.Nrap[0]-1; ++i) 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); ReturnState.Ix2[0][i]
= RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
return(ReturnState); return(ReturnState);
} }
} // namespace ABACUS } // namespace ABACUS

View File

@ -35,12 +35,12 @@ namespace ABACUS {
{}; {};
XXZ_Bethe_State::XXZ_Bethe_State (const XXZ_Bethe_State& RefState) // copy constructor 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)), : Heis_Bethe_State(RefState), sinhlambda(Lambda(RefState.chain, RefState.base)),
coshlambda(Lambda(RefState.chain, RefState.base)),
tanhlambda(Lambda(RefState.chain, RefState.base)) tanhlambda(Lambda(RefState.chain, RefState.base))
{ {
// copy arrays into new ones // copy arrays into new ones
//cout << "Calling XXZ state copy constructor." << endl;
for (int j = 0; j < RefState.chain.Nstrings; ++j) { for (int j = 0; j < RefState.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < RefState.base[j]; ++j) { for (int alpha = 0; alpha < RefState.base[j]; ++j) {
sinhlambda[j][alpha] = RefState.sinhlambda[j][alpha]; sinhlambda[j][alpha] = RefState.sinhlambda[j][alpha];
@ -48,40 +48,29 @@ namespace ABACUS {
tanhlambda[j][alpha] = RefState.tanhlambda[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) XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, int M)
: Heis_Bethe_State(RefChain, M), : Heis_Bethe_State(RefChain, M),
sinhlambda(Lambda(RefChain, M)), coshlambda(Lambda(RefChain, M)), tanhlambda(Lambda(RefChain, M)) sinhlambda(Lambda(RefChain, M)), coshlambda(Lambda(RefChain, M)), tanhlambda(Lambda(RefChain, M))
{ {
//cout << "Here in XXZ BS constructor." << endl; if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0))
//cout << (*this).lambda[0][0] << endl; ABACUSerror("Delta out of range in XXZ_Bethe_State constructor");
//cout << "OK" << endl;
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) ABACUSerror("Delta out of range in XXZ_Bethe_State constructor");
} }
XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase) XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase)
: Heis_Bethe_State(RefChain, RefBase), : Heis_Bethe_State(RefChain, RefBase),
sinhlambda(Lambda(RefChain, RefBase)), coshlambda(Lambda(RefChain, RefBase)), tanhlambda(Lambda(RefChain, RefBase)) sinhlambda(Lambda(RefChain, RefBase)), coshlambda(Lambda(RefChain, RefBase)), tanhlambda(Lambda(RefChain, RefBase))
{ {
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) ABACUSerror("Delta out of range in XXZ_Bethe_State constructor"); if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0))
ABACUSerror("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)) ABACUSerror("Delta out of range in XXZ_Bethe_State constructor");
}
*/
XXZ_Bethe_State& XXZ_Bethe_State::operator= (const XXZ_Bethe_State& RefState) XXZ_Bethe_State& XXZ_Bethe_State::operator= (const XXZ_Bethe_State& RefState)
{ {
if (this != &RefState) { if (this != &RefState) {
chain = RefState.chain; chain = RefState.chain;
base = RefState.base; base = RefState.base;
//offsets = RefState.offsets;
Ix2 = RefState.Ix2; Ix2 = RefState.Ix2;
lambda = RefState.lambda; lambda = RefState.lambda;
BE = RefState.BE; BE = RefState.BE;
@ -93,11 +82,6 @@ namespace ABACUS {
iK = RefState.iK; iK = RefState.iK;
K = RefState.K; K = RefState.K;
lnnorm = RefState.lnnorm; 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; label = RefState.label;
sinhlambda = RefState.sinhlambda; sinhlambda = RefState.sinhlambda;
@ -119,21 +103,16 @@ namespace ABACUS {
for (int alpha = 0; alpha < base[i]; ++alpha) { for (int alpha = 0; alpha < base[i]; ++alpha) {
if (chain.par[i] == 1) { 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); 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 lambda[i][alpha] = atanh(x/sqrt(1.0 + x*x)); // lambda then always initiated real
} }
else if (chain.par[i] == -1) { 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); 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 lambda[i][alpha] = atanh(x/sqrt(1.0 + x*x)); // lambda then always initiated real
} }
else ABACUSerror("Invalid parities in Set_Free_lambdas."); else ABACUSerror("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;
} }
} }
@ -179,8 +158,9 @@ namespace ABACUS {
bool higher_string_on_zero = false; bool higher_string_on_zero = false;
for (int j = 0; j < chain.Nstrings; ++j) { 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 // 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)*/) for (int alpha = 0; alpha < base[j]; ++alpha)
higher_string_on_zero = true; 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; 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. // NOTE: if base[j] == 0, Zero_at_level[j] remains false.
} }
@ -192,14 +172,16 @@ namespace ABACUS {
bool string_coincidence = false; bool string_coincidence = false;
for (int j1 = 0; j1 < chain.Nstrings; ++j1) { for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2) 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))) 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; string_coincidence = true;
} }
bool M_odd_and_onep_on_zero = false; 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 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). // (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; 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; if (Zero_at_level[0] && (base.Mdown % 2) && !is_ground_state) M_odd_and_onep_on_zero = true;
} }
@ -208,12 +190,14 @@ namespace ABACUS {
if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true; 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)); 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) // 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 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; for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites)
|| (Ix2[j][alpha] >= chain.Nsites)) answer = false;
if (!answer) { if (!answer) {
E = 0.0; E = 0.0;
@ -237,17 +221,23 @@ namespace ABACUS {
for (int beta = 0; beta < base[k]; ++beta) { for (int beta = 0; beta < base[k]; ++beta) {
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
sumtheta += (chain.par[j] == chain.par[k]) 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])
: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ; /((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]), : - atan(((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); /(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; 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]]) BE[j][alpha] = ((chain.par[j] == 1) ?
: -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites; 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 () void XXZ_Bethe_State::Compute_BE ()
{ {
@ -265,17 +255,21 @@ namespace ABACUS {
for (int beta = 0; beta < base[k]; ++beta) { for (int beta = 0; beta < base[k]; ++beta) {
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
sumtheta += (chain.par[j] == chain.par[k]) 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])
: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ; /((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]), : - atan(((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); /(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; 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]]) BE[j][alpha] = ((chain.par[j] == 1) ?
: -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites; 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
:
//if (is_nan(BE[j][alpha])) cout << "BE nan: " << j << "\t" << alpha << "\t" << lambda[j][alpha] << "\t" << tanhlambda[j][alpha] << endl; -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]))
- (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
} }
} }
@ -288,15 +282,14 @@ namespace ABACUS {
DP arg = 0.0; DP arg = 0.0;
if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]] if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]]
* tan(0.5 * * 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])
(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 * 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]])
(-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha])) - BE[j][alpha]))
/chain.ta_n_anis_over_2[chain.Str_L[j]]; /chain.ta_n_anis_over_2[chain.Str_L[j]];
if (fabs(arg) < 1.0) { if (fabs(arg) < 1.0) {
new_lambda = atanh(arg); new_lambda = atanh(arg);
@ -316,15 +309,20 @@ namespace ABACUS {
for (int beta = 0; beta < base[k]; ++beta) for (int beta = 0; beta < base[k]; ++beta)
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
sumtheta += (chain.par[j] == chain.par[k]) 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])
: - atan(((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ; /((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]), : - atan(((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); /(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; 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); 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 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 ABACUSerror("Invalid parities in Iterate_BAE."); else ABACUSerror("Invalid parities in Iterate_BAE.");
@ -334,7 +332,6 @@ namespace ABACUS {
new_lambda = atanh(arg); new_lambda = atanh(arg);
} }
//else cout << "Rapidity blows up !\t" << lambda[j][alpha] << "\t" << new_lambda << endl;
} // else } // else
return(new_lambda); return(new_lambda);
@ -357,9 +354,8 @@ namespace ABACUS {
DP delta = 0.0; DP delta = 0.0;
int occupied_strings = 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]; 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; if (occupied_strings == 0) delta = 0.0;
@ -379,28 +375,34 @@ namespace ABACUS {
if ((*this).chain.Str_L[j] > 1) { // else the BAE are already 1 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] log_BAE_reg = DP((*this).chain.Nsites)
+ 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0) * log(sinh((*this).lambda[j][alpha]
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j])) + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0)
/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]))
+ 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 k = 0; k < (*this).chain.Nstrings; ++k)
for (int beta = 0; beta < (*this).base[k]; ++beta) for (int beta = 0; beta < (*this).base[k]; ++beta)
for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) { for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
if ((j != k) || (alpha != beta) || (a != b - 1)) 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 ) log_BAE_reg += log(sinh(((*this).lambda[j][alpha]
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j])) + 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 ) + 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
+ 0.25 * II * PI * (1.0 - (*this).chain.par[k])) - II * (*this).chain.anis)); - ((*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)) 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 ) log_BAE_reg -= log(sinh(((*this).lambda[j][alpha]
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j])) + 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 ) + 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
+ 0.25 * II * PI * (1.0 - (*this).chain.par[k])) + II * (*this).chain.anis)); - ((*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... // The regular LHS of BAE is now defined. Now sum up the deltas...
@ -437,7 +439,8 @@ namespace ABACUS {
for (int j = 0; j < chain.Nstrings; ++j) { for (int j = 0; j < chain.Nstrings; ++j) {
for (int alpha = 0; alpha < base[j]; ++alpha) { 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 += sin(chain.Str_L[j] * chain.anis)
/ (chain.par[j] * cosh(2.0 * lambda[j][alpha]) - cos(chain.Str_L[j] * chain.anis));
} }
} }
@ -448,36 +451,11 @@ namespace ABACUS {
return; 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) void XXZ_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
{ {
if (Gaudin_Red.size() != base.Nraptot) ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix."); if (Gaudin_Red.size() != base.Nraptot)
ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
int index_jalpha; int index_jalpha;
int index_kbeta; int index_kbeta;
@ -504,13 +482,14 @@ namespace ABACUS {
for (int betap = 0; betap < base[kp]; ++betap) { for (int betap = 0; betap < base[kp]; ++betap) {
if (!((j == kp) && (alpha == betap))) if (!((j == kp) && (alpha == betap)))
sum_hbar_XXZ 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], += ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j],
chain.si_n_anis_over_2); chain.Str_L[kp], chain.par[j], chain.par[kp], chain.si_n_anis_over_2);
} }
} }
Gaudin_Red[index_jalpha][index_kbeta] 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); = 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 { else {
@ -518,12 +497,13 @@ namespace ABACUS {
Gaudin_Red[index_jalpha][index_kbeta] = Gaudin_Red[index_jalpha][index_kbeta] =
complex<DP> ((chain.par[j] * chain.par[k] == 1) complex<DP> ((chain.par[j] * chain.par[k] == 1)
? chain.si_n_anis_over_2[4]/(pow(sinhlambda[j][alpha] * coshlambda[k][beta] ? chain.si_n_anis_over_2[4]/(pow(sinhlambda[j][alpha] * coshlambda[k][beta]
- coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) - coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq)
: chain.si_n_anis_over_2[4]/(-pow(coshlambda[j][alpha] * coshlambda[k][beta] : chain.si_n_anis_over_2[4]/(-pow(coshlambda[j][alpha] * coshlambda[k][beta]
- sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) ); - sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) );
else 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], Gaudin_Red[index_jalpha][index_kbeta]
chain.par[j], chain.par[k], chain.si_n_anis_over_2)); = 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_kbeta++;
} }
@ -561,7 +541,8 @@ namespace ABACUS {
result = (nj == nk) ? 0.0 : fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk)]); result = (nj == nk) ? 0.0 : fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk)]);
for (int a = 1; a < ABACUS::min(nj, nk); ++a) result += 2.0 * fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk) + 2*a]); for (int a = 1; a < ABACUS::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]); result += fbar_XXZ(tanhlambda, parj*park, tannzetaover2[nj + nk]);
} }
@ -586,7 +567,8 @@ namespace ABACUS {
{ {
DP result = (nj == nk) ? 0.0 : hbar_XXZ(lambda, fabs(nj - nk), parj*park, 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 < ABACUS::min(nj, nk); ++a) result += 2.0 * hbar_XXZ(lambda, fabs(nj - nk) + 2*a, parj*park, si_n_anis_over_2); for (int a = 1; a < ABACUS::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); result += hbar_XXZ(lambda, nj + nk, parj*park, si_n_anis_over_2);
@ -641,6 +623,6 @@ namespace ABACUS {
ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2); ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
return(ReturnState); return(ReturnState);
} }
} // namespace ABACUS } // namespace ABACUS

View File

@ -64,20 +64,12 @@ namespace ABACUS {
{ {
if (RefChain.Delta <= 1.0) ABACUSerror("Delta too low in XXZ_gpd_Bethe_State constructor"); if (RefChain.Delta <= 1.0) ABACUSerror("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) ABACUSerror("Delta too low in XXZ_gpd_Bethe_State constructor");
}
*/
XXZ_gpd_Bethe_State& XXZ_gpd_Bethe_State::operator= (const XXZ_gpd_Bethe_State& RefState) XXZ_gpd_Bethe_State& XXZ_gpd_Bethe_State::operator= (const XXZ_gpd_Bethe_State& RefState)
{ {
if (this != &RefState) { if (this != &RefState) {
chain = RefState.chain; chain = RefState.chain;
base = RefState.base; base = RefState.base;
//offsets = RefState.offsets;
Ix2 = RefState.Ix2; Ix2 = RefState.Ix2;
lambda = RefState.lambda; lambda = RefState.lambda;
BE = RefState.BE; BE = RefState.BE;
@ -89,11 +81,6 @@ namespace ABACUS {
iK = RefState.iK; iK = RefState.iK;
K = RefState.K; K = RefState.K;
lnnorm = RefState.lnnorm; 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; label = RefState.label;
sinlambda = RefState.sinlambda; sinlambda = RefState.sinlambda;
@ -146,7 +133,6 @@ namespace ABACUS {
for (int alpha = 0; alpha < base[j]; ++alpha) { for (int alpha = 0; alpha < base[j]; ++alpha) {
tanlambda[j][alpha] = tan(lambda[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; return;
@ -161,75 +147,6 @@ namespace ABACUS {
bool answer = true; bool answer = true;
Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level 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 * ABACUS::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 // 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: // 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) //for (int j = 0; j < chain.Nstrings; ++j)
@ -242,7 +159,7 @@ namespace ABACUS {
for (int j = 0; j < chain.Nstrings; ++j) { 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 // 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)*/) 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; higher_string_on_zero = true;
for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = 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. // NOTE: if base[j] == 0, Zero_at_level[j] remains false.
} }
@ -262,8 +179,6 @@ namespace ABACUS {
//if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true; //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 || onep_onem_on_zero)));
answer = !(symmetric_state && (higher_string_on_zero || string_coincidence)); answer = !(symmetric_state && (higher_string_on_zero || string_coincidence));
@ -274,7 +189,8 @@ namespace ABACUS {
// Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp) // 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 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; for (int alpha = 0; alpha < base[j]; ++alpha)
if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
if (!answer) { if (!answer) {
E = 0.0; E = 0.0;
@ -300,14 +216,15 @@ namespace ABACUS {
for (int k = 0; k < chain.Nstrings; ++k) { for (int k = 0; k < chain.Nstrings; ++k) {
for (int beta = 0; beta < base[k]; ++beta) for (int beta = 0; beta < base[k]; ++beta)
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) { 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]) sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])
* chain.ta_n_anis_over_2[2])) /((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); + 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]), 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) chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
+ PI * (2.0 * ABACUS::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0)) + PI * (2.0 * ABACUS::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0))
* floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI); * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
} }
sumtheta *= 2.0; sumtheta *= 2.0;
@ -331,14 +248,15 @@ namespace ABACUS {
for (int k = 0; k < chain.Nstrings; ++k) { for (int k = 0; k < chain.Nstrings; ++k) {
for (int beta = 0; beta < base[k]; ++beta) for (int beta = 0; beta < base[k]; ++beta)
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) { 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]) sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])
* chain.ta_n_anis_over_2[2])) /((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); + 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]), 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) chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
+ PI * (2.0 * ABACUS::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0)) + PI * (2.0 * ABACUS::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0))
* floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI); * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
} }
sumtheta *= 2.0; sumtheta *= 2.0;
@ -355,170 +273,19 @@ namespace ABACUS {
DP arg0 = 0.5 * (2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) 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]); + PI * floor(0.5 + lambda[j][alpha]/PI)) - BE[j][alpha]);
DP arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan( DP arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(arg0);
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) return(atan(arg) + PI * floor(0.5 + arg0/PI));
//+ 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 * ABACUS::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 * ABACUS::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 XXZ_gpd_Bethe_State::Check_Rapidities()
{ {
bool nonan = true; bool nonan = true;
for (int j = 0; j < chain.Nstrings; ++j) for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) if (nonan) nonan = ((!is_nan(lambda[j][alpha])) for (int alpha = 0; alpha < base[j]; ++alpha)
//&& (lambda[j][alpha] > -0.5*PI*chain.Str_L[j]) if (nonan) nonan = ((!is_nan(lambda[j][alpha])));
//&& (lambda[j][alpha] <= 0.5*PI*chain.Str_L[j])
);
bool all_within_pi_interval = true; bool all_within_pi_interval = true;
DP min_lambda = 10.0; DP min_lambda = 10.0;
@ -544,9 +311,8 @@ namespace ABACUS {
DP delta = 0.0; DP delta = 0.0;
int occupied_strings = 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]; 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; if (occupied_strings == 0) delta = 0.0;
@ -567,8 +333,9 @@ namespace ABACUS {
if ((*this).chain.Str_L[j] > 1) { // else the BAE are already 1 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 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)) * ((*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))); /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 k = 0; k < (*this).chain.Nstrings; ++k)
for (int beta = 0; beta < (*this).base[k]; ++beta) for (int beta = 0; beta < (*this).base[k]; ++beta)
@ -576,13 +343,13 @@ namespace ABACUS {
if ((j != k) || (alpha != beta) || (a != b - 1)) 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 )) 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 )) - ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ))
- II * (*this).chain.anis)); - II * (*this).chain.anis));
if ((j != k) || (alpha != beta) || (a != b + 1)) 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 )) 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 )) - ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ))
+ II * (*this).chain.anis)); + II * (*this).chain.anis));
} }
@ -631,32 +398,6 @@ namespace ABACUS {
return; 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) void XXZ_gpd_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
{ {
@ -689,7 +430,7 @@ namespace ABACUS {
if (!((j == kp) && (alpha == betap))) if (!((j == kp) && (alpha == betap)))
sum_hbar_XXZ sum_hbar_XXZ
+= ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp], += ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp],
chain.si_n_anis_over_2); chain.si_n_anis_over_2);
} }
} }
@ -701,7 +442,7 @@ namespace ABACUS {
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
Gaudin_Red[index_jalpha][index_kbeta] = Gaudin_Red[index_jalpha][index_kbeta] =
complex<DP> (chain.si_n_anis_over_2[4]/(pow(sinlambda[j][alpha] * coslambda[k][beta] 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)); - coslambda[j][alpha] * sinlambda[k][beta], 2.0) + sinhetasq));
else else
Gaudin_Red[index_jalpha][index_kbeta] = complex<DP> (ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], 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)); chain.Str_L[k], chain.si_n_anis_over_2));
@ -736,7 +477,8 @@ namespace ABACUS {
result = (nj == nk) ? 0.0 : fbar_XXZ_gpd(tanlambda, tanhnetaover2[fabs(nj - nk)]); result = (nj == nk) ? 0.0 : fbar_XXZ_gpd(tanlambda, tanhnetaover2[fabs(nj - nk)]);
for (int a = 1; a < ABACUS::min(nj, nk); ++a) result += 2.0 * fbar_XXZ_gpd(tanlambda, tanhnetaover2[fabs(nj - nk) + 2*a]); for (int a = 1; a < ABACUS::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]); result += fbar_XXZ_gpd(tanlambda, tanhnetaover2[nj + nk]);
} }
@ -753,7 +495,8 @@ namespace ABACUS {
{ {
DP result = (nj == nk) ? 0.0 : hbar_XXZ_gpd(lambda, fabs(nj - nk), 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 < ABACUS::min(nj, nk); ++a) result += 2.0 * hbar_XXZ_gpd(lambda, fabs(nj - nk) + 2*a, si_n_anis_over_2); for (int a = 1; a < ABACUS::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); result += hbar_XXZ_gpd(lambda, nj + nk, si_n_anis_over_2);
@ -808,6 +551,6 @@ namespace ABACUS {
ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2); ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
return(ReturnState); return(ReturnState);
} }
} // namespace ABACUS } // namespace ABACUS

View File

@ -19,240 +19,201 @@ using namespace ABACUS;
namespace ABACUS { namespace ABACUS {
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b) inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{ {
complex<DP> ans = 0.0; complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) { for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b))) if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta] 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))); + 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
}
} }
} }
return(ans);
} }
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;
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b) for (int j = 0; j < A.chain.Nstrings; ++j) {
{ for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
complex<DP> ans = 0.0; for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
for (int j = 0; j < A.chain.Nstrings; ++j) { ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
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);
} }
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]
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) + 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]
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 - 1.0)) )));
+ 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 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));
}
for (int j = 0; j < A.chain.Nstrings; ++j) complex<DP> ln_Overlap (XXX_Bethe_State& A, XXX_Bethe_State& B)
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) // This function returns the overlap of states A and B.
ln_prod3 += ln_Fn_F (A, j, alpha, a - 1); // The A and B states can contain strings.
// ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta))); // IMPORTANT ASSUMPTIONS:
// - State B is an eigenstate of the model on which the overlap measure is defined
for (int k = 0; k < B.chain.Nstrings; ++k) // Check that A and B are compatible: same Mdown
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
for (int b = 1; b <= B.chain.Str_L[k]; ++b) { if (A.base.Mdown != B.base.Mdown) return(complex<DP>(-300.0)); // overlap vanishes
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); // 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_prod3 = 0.0;
complex<DP> ln_prod4 = 0.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));
}
} }
// ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta))); // Define regularized products in prefactors
// Now proceed to build the Hm2P matrix 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);
SQMat_CX Hm2P(0.0, A.base.Mdown); // ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
int index_a = 0; for (int k = 0; k < B.chain.Nstrings; ++k)
int index_b = 0; 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> sum1 = 0.0; // Now proceed to build the Hm2P matrix
//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) { SQMat_CX Hm2P(0.0, A.base.Mdown);
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
index_b = 0; int index_a = 0;
int 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)) * complex<DP> sum1 = 0.0;
// (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25); 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;
for (int k = 0; k < B.chain.Nstrings; ++k) { for (int j = 0; j < A.chain.Nstrings; ++j) {
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) { for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int b = 1; b <= B.chain.Str_L[k]; ++b) { for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
if (B.chain.Str_L[k] == 1) { index_b = 0;
// use simplified code for one-string here: original form of Hm2P matrix 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) {
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * if (B.chain.Str_L[k] == 1) {
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)); // use simplified code for one-string here: original form of Hm2P matrix
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 Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
//- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]); 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]);
else { Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II),
complex<DP> (A.chain.Nsites)); // careful !
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b); Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
else if (b == B.chain.Str_L[k]) { ;
}
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2); else {
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); if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i); else if (b == B.chain.Str_L[k]) {
sum1 = 0.0; 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);
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]); 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 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) sum1 = 0.0;
* 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_K (A, j, alpha, a, B, k, beta, 0)
* exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) * sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]); * 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]);
//sum2 = 0.0; for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
//for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[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]);
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]); 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) 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 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;
Hm2P[index_a][index_b] = prod_num * sum1;
} // else if (b == B.chain.Str_L[k]) } // else if (b == B.chain.Str_L[k])
} // else } // else
index_b++; index_b++;
}}} // sums over k, beta, b }}} // sums over k, beta, b
index_a++; index_a++;
}}} // sums over j, alpha, a }}} // sums over j, alpha, a
//cout << "Matrix: " << endl;
//Hm2P.Print();
complex<DP> det = lndet_LU_CX_dstry(Hm2P); complex<DP> det = lndet_LU_CX_dstry(Hm2P);
/* complex<DP> ln_overlap = 0.5 * (-ln_prod3 + ln_prod4) + det - 0.5 * (A.lnnorm + B.lnnorm);
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 cout << "ln_overlap: " << endl << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
// << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl; << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
return(ln_form_factor_sq); return(ln_overlap);
*/
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 ABACUS } // namespace ABACUS

View File

@ -19,236 +19,222 @@ using namespace ABACUS;
namespace ABACUS { namespace ABACUS {
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b) inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{ {
complex<DP> ans = 0.0; complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) { for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b))) if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta] 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))); + 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
}
} }
} }
return(ans);
} }
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;
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b) for (int j = 0; j < A.chain.Nstrings; ++j) {
{ for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
complex<DP> ans = 0.0; for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
for (int j = 0; j < A.chain.Nstrings; ++j) { ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
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);
} }
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]
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) + 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]
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 - 1.0)) )));
+ 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) ABACUSerror("Incompatible XXX_Chains in Smin matrix element.");
// Check that A and B are Mdown-compatible:
if (A.base.Mdown != B.base.Mdown + 1) ABACUSerror("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 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));
}
for (int j = 0; j < A.chain.Nstrings; ++j) complex<DP> ln_Smin_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) // This function returns the natural log of the S^- operator matrix element.
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1); // The A and B states can contain strings.
// ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta))); // Check that the two states are compatible
for (int k = 0; k < B.chain.Nstrings; ++k) if (A.chain != B.chain) ABACUSerror("Incompatible XXX_Chains in Smin matrix element.");
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
for (int b = 1; b <= B.chain.Str_L[k]; ++b) { // Check that A and B are Mdown-compatible:
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); if (A.base.Mdown != B.base.Mdown + 1)
ABACUSerror("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) {
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);
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);
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);
}
} }
// ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta))); // Define regularized products in prefactors
// Now proceed to build the Hm matrix 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);
SQMat_CX Hm(0.0, A.base.Mdown); 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);
}
int index_a = 0; // Now proceed to build the Hm matrix
int index_b = 0;
complex<DP> sum1 = 0.0; SQMat_CX Hm(0.0, A.base.Mdown);
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) { int index_a = 0;
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { int index_b = 0;
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
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;
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)) * for (int j = 0; j < A.chain.Nstrings; ++j) {
(A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25); for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
for (int k = 0; k < B.chain.Nstrings; ++k) { index_b = 0;
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) { 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);
// use simplified code for one-string here: original form of Hm2P matrix 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) {
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * if (B.chain.Str_L[k] == 1) {
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)); // use simplified code for one-string here: original form of Hm2P matrix
Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2; 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]);
} // if (B.chain.Str_L == 1) Prod_powerN = pow((B.lambda[k][beta] + II * 0.5) /(B.lambda[k][beta] - II * 0.5),
complex<DP> (B.chain.Nsites));
else { Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b); } // if (B.chain.Str_L == 1)
else if (b == B.chain.Str_L[k]) {
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2); else {
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); if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i); else if (b == B.chain.Str_L[k]) {
sum1 = 0.0; 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);
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]); 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 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) sum1 = 0.0;
* 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_K (A, j, alpha, a, B, k, beta, 0)
* exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) * sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]); * 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)
sum2 = 0.0;
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[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]);
*/ prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
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) 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))); 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 // include all string contributions F_B_0 in this term
Hm[index_a][index_b] = prod_num * sum1; Hm[index_a][index_b] = prod_num * sum1;
} // else if (b == B.chain.Str_L[k]) } // else if (b == B.chain.Str_L[k])
} // else } // else
index_b++; index_b++;
}}} // sums over k, beta, b }}} // sums over k, beta, b
// now define the elements Hm[a][M] // 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] = one_over_A_lambda_sq_plus_1over2sq;
index_a++; index_a++;
}}} // sums over j, alpha, 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) 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; + 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
return(0.5 * ln_ME_sq); // Return ME, not MEsq
} }
} // namespace ABACUS } // namespace ABACUS

View File

@ -19,325 +19,315 @@ using namespace ABACUS;
namespace ABACUS { namespace ABACUS {
inline complex<DP> ln_Fn_F (XXZ_Bethe_State& B, int k, int beta, int b) inline complex<DP> ln_Fn_F (XXZ_Bethe_State& B, int k, int beta, int b)
{ {
complex<DP> ans = 0.0; complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0; complex<DP> prod_temp = 1.0;
int counter = 0; int counter = 0;
int arg = 0; int arg = 0;
int absarg = 0; int absarg = 0;
int par_comb_1, par_comb_2; int par_comb_1, par_comb_2;
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0; 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]; 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 alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) { for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b))) { if (!((j == k) && (alpha == beta) && (a == b))) {
arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
absarg = abs(arg);
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); absarg = abs(arg);
/* prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta]
prod_temp *= 0.5 * //done later... - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta]) * (A.chain.co_n_anis_over_2[absarg] * par_comb_1
* (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k]) - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta]
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) - A.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]) * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1
+ B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) ); + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
*/
prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta]) if (counter++ > 100) { // we do at most 100 products before taking a log
* (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) ans += log(prod_temp);
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) prod_temp = 1.0;
* (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)); counter = 0;
} }
}}}
if (counter++ > 100) { // we do at most 100 products before taking a log return(ans + log(prod_temp));
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) ABACUSerror("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;
ABACUSerror("Incompatible Mdown between the two states in Smin matrix element!");
} }
// Compute the sinh and cosh of rapidities 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);
A.Compute_sinhlambda(); return(4.0/(
A.Compute_coshlambda(); ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
B.Compute_sinhlambda(); * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
B.Compute_coshlambda(); - 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])) )
));
// 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))); 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));
}
// Define regularized products in prefactors 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.
for (int j = 0; j < A.chain.Nstrings; ++j) // Check that the two states are compatible
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))); if (A.chain != B.chain) ABACUSerror("Incompatible XXZ_Chains in Smin matrix element.");
for (int k = 0; k < B.chain.Nstrings; ++k) // Check that A and B are Mdown-compatible:
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
for (int b = 1; b <= B.chain.Str_L[k]; ++b) { if (A.base.Mdown != B.base.Mdown + 1) {
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta]; cout << "A.base.Mdown = " << A.base.Mdown << "\tB.base.Mdown = " << B.base.Mdown << endl;
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1); cout << "A: " << A << endl << "B: " << B << endl;
ABACUSerror("Incompatible Mdown between the two states in Smin matrix element!");
} }
ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis))); // Compute the sinh and cosh of rapidities
// Now proceed to build the Hm matrix A.Compute_sinhlambda();
A.Compute_coshlambda();
B.Compute_sinhlambda();
B.Compute_coshlambda();
SQMat_CX Hm(0.0, A.base.Mdown); // Some convenient arrays
int index_a = 0; Lambda re_ln_Fn_F_B_0(B.chain, B.base);
int index_b = 0; 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> sum1 = 0.0; complex<DP> ln_prod1 = 0.0;
complex<DP> sum2 = 0.0; complex<DP> ln_prod2 = 0.0;
complex<DP> prod_num = 0.0; complex<DP> ln_prod3 = 0.0;
complex<DP> Fn_K_0_G_0 = 0.0; complex<DP> ln_prod4 = 0.0;
complex<DP> Prod_powerN = 0.0;
complex<DP> Fn_K_1_G_2 = 0.0; for (int i = 0; i < A.chain.Nstrings; ++i)
complex<DP> one_over_A_sinhlambda_sq_plus_sinzetaover2sq; 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 j = 0; j < A.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) { for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
index_b = 0; 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) one_over_A_sinhlambda_sq_plus_sinzetaover2sq
+ 0.25 * II * PI * (1.0 - A.chain.par[j]))) = 1.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
* (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])))
+ 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)
+ pow(sin(0.5*A.chain.anis), 2.0)); + 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 k = 0; k < B.chain.Nstrings; ++k) {
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) { for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
for (int b = 1; b <= B.chain.Str_L[k]; ++b) { for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
if (B.chain.Str_L[k] == 1) { if (B.chain.Str_L[k] == 1) {
// use simplified code for one-string here: original form of Hm matrix // 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) * 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); 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) * 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); 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 ? 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]
/(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]) + 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]
(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]) - 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]) :
, complex<DP> (B.chain.Nsites)); (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; Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
} // if (B.chain.Str_L == 1) } // if (B.chain.Str_L == 1)
else { else {
if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b); 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]) { else if (b == B.chain.Str_L[k]) {
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2); 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); 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); 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); 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 = 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, 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]) 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] * 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]); - 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) for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, 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]); exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
/* prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1]
sum2 = 0.0; - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]); 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;
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) } // else if (b == B.chain.Str_L[k])
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinzeta); } // else
// include all string contributions F_B_0 in this term
Hm[index_a][index_b] = prod_num * sum1; index_b++;
}}} // sums over k, beta, b
} // else if (b == B.chain.Str_L[k]) // now define the elements Hm[a][M]
} // else
index_b++; Hm[index_a][B.base.Mdown] = one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
}}} // sums over k, beta, b
// now define the elements Hm[a][M] index_a++;
}}} // sums over j, alpha, a
Hm[index_a][B.base.Mdown] = one_over_A_sinhlambda_sq_plus_sinzetaover2sq; 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;
index_a++; return(0.5 * ln_ME_sq); // Return ME, not MEsq
}}} // 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 ABACUS } // namespace ABACUS

View File

@ -19,300 +19,266 @@ using namespace ABACUS;
namespace ABACUS { namespace ABACUS {
inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b) inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
{ {
complex<DP> ans = 0.0; complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0; complex<DP> prod_temp = 1.0;
int counter = 0; int counter = 0;
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) { 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))) { if (!((j == k) && (alpha == beta) && (a == b))) {
// arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); prod_temp *= -II * (B.sinlambda[j][alpha] * B.coslambda[k][beta] - B.coslambda[j][alpha] * B.sinlambda[k][beta])
// absarg = abs(arg); * 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)));
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 if (counter++ > 10) { // we do at most 10 products before taking a log
ans += log(prod_temp); ans += log(prod_temp);
prod_temp = 1.0; prod_temp = 1.0;
counter = 0; counter = 0;
} }
}}} }}}
// return(ans); // return(ans);
return(ans + log(prod_temp)); 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) ABACUSerror("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) ABACUSerror("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))); 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;
// 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) {
for (int j = 0; j < A.chain.Nstrings; ++j) prod_temp *= -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) * cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
for (int a = 1; a <= A.chain.Str_L[j]; ++a) (A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1); * sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis))); if (counter++ > 25) { // we do at most 25 products before taking a log
ans += log(prod_temp);
prod_temp = 1.0;
counter = 0;
}
}}}
for (int k = 0; k < B.chain.Nstrings; ++k) // return(ans);
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) return(ans + log(prod_temp));
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); 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/(( -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)
{
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)
ABACUSerror("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)
ABACUSerror("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))));
// 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));
}
} }
ln_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis))); DP logabssinheta = log(abs(sinh(A.chain.anis)));
// Now proceed to build the Hm matrix // Define regularized products in prefactors
SQMat_CX Hm(0.0, A.base.Mdown); 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);
int index_a = 0; ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis)));
int index_b = 0;
complex<DP> sum1 = 0.0; for (int k = 0; k < B.chain.Nstrings; ++k)
complex<DP> sum2 = 0.0; for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
complex<DP> prod_num = 0.0; for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
complex<DP> Fn_K_0_G_0 = 0.0; if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
complex<DP> Prod_powerN = 0.0; else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
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) { ln_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis)));
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
index_b = 0; // Now proceed to build the Hm matrix
one_over_A_sinlambda_sq_plus_sinhetaover2sq = -1.0/((sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2... SQMat_CX Hm(0.0, A.base.Mdown);
+ 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) { int index_a = 0;
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) { int index_b = 0;
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
if (B.chain.Str_L[k] == 1) { 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;
// use simplified code for one-string here: original form of Hm2P matrix 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) {
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * index_b = 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]) one_over_A_sinlambda_sq_plus_sinhetaover2sq =
/(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]), -1.0/((sin(A.lambda[j][alpha] // -sign from 1/(sinh^2... to -1/(sin^2...
complex<DP> (B.chain.Nsites)); + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a))) *
(sin(A.lambda[j][alpha] // -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));
Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2; 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) {
else { if (B.chain.Str_L[k] == 1) {
if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b); // use simplified code for one-string here: original form of Hm2P matrix
else if (b == B.chain.Str_L[k]) {
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2); Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i); 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);
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2); Prod_powerN = pow((B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1]
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i); + 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));
sum1 = 0.0; Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
}
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]); else {
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] else if (b == B.chain.Str_L[k]) {
- 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) 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);
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) * Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]); for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
/*
sum2 = 0.0;
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]); sum1 = 0.0;
*/
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) sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
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; 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]);
} // else if (b == B.chain.Str_L[k]) for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
} // else
index_b++; sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
}}} // sums over k, beta, b exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
// now define the elements Hm[a][M] prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1]
- ln_FunctionG[B.chain.Str_L[k]] + logabssinheta);
Hm[index_a][B.base.Mdown] = one_over_A_sinlambda_sq_plus_sinhetaover2sq; 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
index_a++; Hm[index_a][index_b] = prod_num * sum1;
}}} // 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) } // else if (b == B.chain.Str_L[k])
+ 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinheta - A.lnnorm - B.lnnorm; } // else
//return(ln_ME_sq); index_b++;
return(0.5 * ln_ME_sq); // Return ME, not MEsq }}} // 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(0.5 * ln_ME_sq); // Return ME, not MEsq
}
} // namespace ABACUS } // namespace ABACUS

View File

@ -18,305 +18,307 @@ using namespace std;
using namespace ABACUS; using namespace ABACUS;
namespace ABACUS { namespace ABACUS {
inline complex<DP> phi(complex<DP> x){return x;} inline complex<DP> phi(complex<DP> x){return x;}
inline complex<DP> a(complex<DP> x){return 1;} 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> b(complex<DP> x,complex<DP> y, complex<DP> eta)
inline complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);} { 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) inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{ {
complex<DP> ans = 0.0; complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) { 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)));
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);
} }
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;
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) 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) {
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta] 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))) + 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) ABACUSerror("Incompatible XXX_Chains in Smm matrix element.");
// Check that A and B are compatible: same Mdown
if (A.base.Mdown != B.base.Mdown + 2) ABACUSerror("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) return(ans);
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)); 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)
index++; {
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;
// This function returns the natural log of the S^z operator matrix element.
// The A and B states can contain strings.
// A is the averaging state.
// Check that the two states refer to the same XXX_Chain
if (A.chain != B.chain)
ABACUSerror("Incompatible XXX_Chains in Smm matrix element.");
// Check that A and B are compatible: same Mdown
if (A.base.Mdown != B.base.Mdown + 2)
ABACUSerror("Incompatible Mdown between the two states in Smm matrix element!");
// 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));
} }
}
Lambda re_ln_Fn_F_B_0(B.chain, B.base); complex<DP> ln_prod1 = 0.0;
Lambda im_ln_Fn_F_B_0(B.chain, B.base); complex<DP> ln_prod2 = 0.0;
Lambda re_ln_Fn_G_0(B.chain, B.base); complex<DP> ln_prod3 = 0.0;
Lambda im_ln_Fn_G_0(B.chain, B.base); complex<DP> ln_prod4 = 0.0;
Lambda re_ln_Fn_G_2(B.chain, B.base);
Lambda im_ln_Fn_G_2(B.chain, B.base); 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;
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));
} }
return(0.5 * result); // Return ME, not MEsq
} }
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 ABACUS } // namespace ABACUS

View File

@ -19,234 +19,230 @@ using namespace ABACUS;
namespace ABACUS { namespace ABACUS {
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b) inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{ {
complex<DP> ans = 0.0; complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) { for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b))) if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta] 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))); + 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
}
} }
} }
return(ans);
} }
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;
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b) for (int j = 0; j < A.chain.Nstrings; ++j) {
{ for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
complex<DP> ans = 0.0; for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
for (int j = 0; j < A.chain.Nstrings; ++j) { ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
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);
} }
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]
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) + 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]
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 - 1.0)) )));
+ 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) ABACUSerror("Incompatible XXX_Chains in Sz matrix element.");
// Check that A and B are compatible: same Mdown
if (A.base.Mdown != B.base.Mdown) ABACUSerror("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 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));
}
for (int j = 0; j < A.chain.Nstrings; ++j) complex<DP> ln_Sz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) // This function returns the natural log of the S^z operator matrix element.
ln_prod3 += ln_Fn_F (A, j, alpha, a - 1); // The A and B states can contain strings.
// ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta))); // Check that the two states refer to the same XXX_Chain
for (int k = 0; k < B.chain.Nstrings; ++k) if (A.chain != B.chain) ABACUSerror("Incompatible XXX_Chains in Sz matrix element.");
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
for (int b = 1; b <= B.chain.Str_L[k]; ++b) { // Check that A and B are compatible: same Mdown
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); if (A.base.Mdown != B.base.Mdown) ABACUSerror("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));
}
} }
// ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta))); // Define regularized products in prefactors
// Now proceed to build the Hm2P matrix 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);
SQMat_CX Hm2P(0.0, A.base.Mdown); // ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
int index_a = 0; for (int k = 0; k < B.chain.Nstrings; ++k)
int index_b = 0; 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> sum1 = 0.0; // ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
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) { // Now proceed to build the Hm2P matrix
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
index_b = 0; SQMat_CX Hm2P(0.0, A.base.Mdown);
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)) * int index_a = 0;
(A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25); int index_b = 0;
for (int k = 0; k < B.chain.Nstrings; ++k) { complex<DP> sum1 = 0.0;
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) { complex<DP> sum2 = 0.0;
for (int b = 1; b <= B.chain.Str_L[k]; ++b) { 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;
if (B.chain.Str_L[k] == 1) { 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) {
// use simplified code for one-string here: original form of Hm2P matrix index_b = 0;
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 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)) *
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]); (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
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)); 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) {
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2 if (B.chain.Str_L[k] == 1) {
- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
} // use simplified code for one-string here: original form of Hm2P matrix
else { 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]);
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b); Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II),
else if (b == B.chain.Str_L[k]) { complex<DP> (B.chain.Nsites));
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2); Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i); - two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
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; else {
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]); 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]) {
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
- 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) 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 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) * sum1 = 0.0;
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
sum2 = 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]);
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]); 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]);
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 = 1; jsum < B.chain.Str_L[k]; ++jsum)
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum) sum1 -= Fn_L (A, j, alpha, a, B, k, beta, 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 exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq); sum2 = 0.0;
} // else if (b == B.chain.Str_L[k]) for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)
} // else sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
index_b++; prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
}}} // sums over k, beta, b
index_a++; for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
}}} // sums over j, alpha, a 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
//cout << "Matrix: " << endl; Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq);
//Hm2P.Print();
DP det = real(lndet_LU_CX_dstry(Hm2P)); } // else if (b == B.chain.Str_L[k])
} // else
complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4) index_b++;
// + 2.0 * real(lndet_LU_CX_dstry(Hm2P)) }}} // sums over k, beta, b
+ 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 index_a++;
// << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl; }}} // sums over j, alpha, a
//return(ln_ME_sq); DP det = real(lndet_LU_CX_dstry(Hm2P));
return(0.5 * ln_ME_sq); // Return ME, not MEsq
} complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
+ 2.0 * det
- A.lnnorm - B.lnnorm;
return(0.5 * ln_ME_sq); // Return ME, not MEsq
}
} // namespace ABACUS } // namespace ABACUS

View File

@ -41,21 +41,15 @@ namespace ABACUS {
arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
absarg = abs(arg); 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));
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 if (counter++ > 100) { // we do at most 100 products before taking a log
@ -90,19 +84,14 @@ namespace ABACUS {
arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
absarg = abs(arg); absarg = abs(arg);
/* prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta]
prod_temp *= 0.5 * - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
((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
* (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] * par_comb_2)
- 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]
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[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]) * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1
+ A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) ); + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
*/
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 if (counter++ > 100) { // we do at most 100 products before taking a log
ans += log(prod_temp); ans += log(prod_temp);
@ -213,8 +202,6 @@ namespace ABACUS {
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
ln_Fn_F_B_0 = 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, 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); 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); 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)); re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
@ -267,11 +254,12 @@ namespace ABACUS {
index_b = 0; 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) two_over_A_sinhlambda_sq_plus_sinzetaover2sq
+ 0.25 * II * PI * (1.0 - A.chain.par[j]))) = 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
* (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])))
+ 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)
+ pow(sin(0.5*A.chain.anis), 2.0)); + 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 k = 0; k < B.chain.Nstrings; ++k) {
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) { for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
@ -287,16 +275,19 @@ namespace ABACUS {
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); 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 ? 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]
/(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]) + 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]
/(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]) + 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)); , 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
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); * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinzeta);
} }
@ -314,7 +305,8 @@ namespace ABACUS {
sum1 = 0.0; 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, 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]) 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] * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
@ -327,9 +319,11 @@ namespace ABACUS {
sum2 = 0.0; sum2 = 0.0;
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]); 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); 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) for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logabssinzeta); prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logabssinzeta);
@ -348,12 +342,8 @@ namespace ABACUS {
DP re_ln_det = real(lndet_LU_CX_dstry(Hm2P)); 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) 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; + 2.0 * 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 return(0.5 * ln_ME_sq); // Return ME, not MEsq
} }
@ -405,14 +395,14 @@ namespace ABACUS {
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha) for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
for (int a = 1; a <= A.chain.Str_L[i]; ++a) 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) 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]))); + 0.25 * II * PI * (1.0 - A.chain.par[i])));
complex<DP> shB; complex<DP> shB;
for (int i = 0; i < B.chain.Nstrings; ++i) for (int i = 0; i < B.chain.Nstrings; ++i)
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha) for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
for (int a = 1; a <= B.chain.Str_L[i]; ++a) 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) 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) + 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) //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])))); // + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
ln_prod2 += log(shB); ln_prod2 += log(shB);

View File

@ -19,301 +19,265 @@ using namespace ABACUS;
namespace ABACUS { namespace ABACUS {
inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b) inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
{ {
complex<DP> ans = 0.0; complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0; complex<DP> prod_temp = 1.0;
int counter = 0; int counter = 0;
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) { for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
/* if (!((j == k) && (alpha == beta) && (a == b))) {
if (!((j == k) && (alpha == beta) && (a == b))) prod_temp *= -II * (B.sinlambda[j][alpha] * B.coslambda[k][beta] - B.coslambda[j][alpha] * B.sinlambda[k][beta])
ans += log(-II * sin(B.lambda[j][alpha] - B.lambda[k][beta] * cosh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
+ 0.5 * II * B.chain.eta * (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 (!((j == k) && (alpha == beta) && (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;
}
// 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]) return(ans + log(prod_temp));
* 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) ABACUSerror("Incompatible XXZ_gpd_Chains in Sz matrix element.");
// Check that A and B are compatible: same Mdown
if (A.base.Mdown != B.base.Mdown) ABACUSerror("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))); 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;
// 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) {
for (int j = 0; j < A.chain.Nstrings; ++j) prod_temp *= -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) * cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
for (int a = 1; a <= A.chain.Str_L[j]; ++a) (A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1); * sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis))); if (counter++ > 25) { // we do at most 25 products before taking a log
ans += log(prod_temp);
prod_temp = 1.0;
counter = 0;
}
}}}
for (int k = 0; k < B.chain.Nstrings; ++k) return(ans + log(prod_temp));
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]; 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)
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1); {
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)
{
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) ABACUSerror("Incompatible XXZ_gpd_Chains in Sz matrix element.");
// Check that A and B are compatible: same Mdown
if (A.base.Mdown != B.base.Mdown)
ABACUSerror("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));
}
} }
ln_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis))); DP logabssinheta = log(abs(sinh(A.chain.anis)));
// Now proceed to build the Hm2P matrix // Define regularized products in prefactors
SQMat_CX Hm2P(0.0, A.base.Mdown); 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);
int index_a = 0; ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis)));
int index_b = 0;
complex<DP> sum1 = 0.0; for (int k = 0; k < B.chain.Nstrings; ++k)
complex<DP> sum2 = 0.0; for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
complex<DP> prod_num = 0.0; for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
complex<DP> Fn_K_0_G_0 = 0.0; if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
complex<DP> Prod_powerN = 0.0; else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
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) { ln_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis)));
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
index_b = 0; // Now proceed to build the Hm2P matrix
two_over_A_sinlambda_sq_plus_sinhetaover2sq = -2.0/((sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2... SQMat_CX Hm2P(0.0, A.base.Mdown);
+ 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) { int index_a = 0;
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) { int index_b = 0;
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
if (B.chain.Str_L[k] == 1) { 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;
// use simplified code for one-string here: original form of Hm2P matrix 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) {
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * index_b = 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]) two_over_A_sinlambda_sq_plus_sinhetaover2sq
/(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]), = -2.0/((sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
complex<DP> (B.chain.Nsites)); + 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));
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2 for (int k = 0; k < B.chain.Nstrings; ++k) {
- two_over_A_sinlambda_sq_plus_sinhetaover2sq * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinheta); 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) {
else { // use simplified code for one-string here: original form of Hm2P matrix
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b); Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
else if (b == B.chain.Str_L[k]) { 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);
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2); Prod_powerN = pow((B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1]
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i); + 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));
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2); Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i); - two_over_A_sinlambda_sq_plus_sinhetaover2sq * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinheta);
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]); else {
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] else if (b == B.chain.Str_L[k]) {
- 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) 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);
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) * Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]); for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
sum2 = 0.0; sum1 = 0.0;
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]); sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0)
* exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinheta); 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 = 2; jsum <= B.chain.Str_L[k]; ++jsum) for (int jsum = 1; 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); 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]);
} // else if (b == B.chain.Str_L[k]) sum2 = 0.0;
} // else
index_b++; for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)
}}} // sums over k, beta, b sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
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) prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1]
+ 2.0 * real(lndet_LU_CX_dstry(Hm2P)) - A.lnnorm - B.lnnorm; - ln_FunctionG[B.chain.Str_L[k]] + logabssinheta);
//cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm << "\t" for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
// << lndet_LU_CX(Hm2P) << endl; 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
//return(ln_ME_sq); Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinlambda_sq_plus_sinhetaover2sq);
return(0.5 * ln_ME_sq); // Return ME, not MEsq
} } // 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;
return(0.5 * ln_ME_sq); // Return ME, not MEsq
}
} // namespace ABACUS } // namespace ABACUS

View File

@ -20,499 +20,355 @@ using namespace ABACUS;
namespace ABACUS { namespace ABACUS {
inline complex<DP> phi(complex<DP> x){return x;} inline complex<DP> phi(complex<DP> x){return x;}
inline complex<DP> a(complex<DP> x){return 1;} 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> 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> 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) inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{ {
complex<DP> ans = 0.0; complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) { for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b))) if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta] 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))); + 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
}
} }
} }
return(ans);
} }
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;
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b) for (int j = 0; j < A.chain.Nstrings; ++j) {
{ for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
complex<DP> ans = 0.0; for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
for (int j = 0; j < A.chain.Nstrings; ++j) { ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
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);
} }
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_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b) 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(1.0/((A.lambda[j][alpha] - B.lambda[k][beta] 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 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
* (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)) ))); * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.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) complex<DP> ln_Szm_p_Smz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
{ {
//clock_t start_time_local = clock(); //clock_t start_time_local = clock();
//A has to be the ground state! //A has to be the ground state!
// This function returns the natural log of the S^z operator matrix element. // This function returns the natural log of the S^z operator matrix element.
// The A and B states can contain strings. // The A and B states can contain strings.
// Check that the two states refer to the same XXX_Chain // Check that the two states refer to the same XXX_Chain
if (A.chain != B.chain) ABACUSerror("Incompatible XXX_Chains in Szm_p_Smz matrix element."); if (A.chain != B.chain) ABACUSerror("Incompatible XXX_Chains in Szm_p_Smz matrix element.");
// Check that A and B are compatible: same Mdown // Check that A and B are compatible: same Mdown
if (A.base.Mdown != B.base.Mdown + 1) ABACUSerror("Incompatible Mdown between the two states in SzSm_p_SmSz matrix element!"); if (A.base.Mdown != B.base.Mdown + 1)
ABACUSerror("Incompatible Mdown between the two states in SzSm_p_SmSz matrix element!");
//if (B.type_id > 999999LL) return(complex<DP>(-300.0)); //if (B.type_id > 999999LL) return(complex<DP>(-300.0));
//add a delta to the origin of the centered strings //add a delta to the origin of the centered strings
for (int i = 0; i < A.chain.Nstrings; ++i) for (int i = 0; i < A.chain.Nstrings; ++i)
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha) 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; 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 i = 0; i < B.chain.Nstrings; ++i)
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha) 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; if(abs(B.lambda[i][alpha])<5.55112e-5)B.lambda[i][alpha]=5.55112e-5;
// Some convenient arrays // Some convenient arrays
complex<DP> i=complex<DP>(0.0,1.0); complex<DP> i=complex<DP>(0.0,1.0);
complex<DP> eta=-i; complex<DP> eta=-i;
complex<DP> ln_prod = complex<DP>(0.0,0.0); complex<DP> ln_prod = complex<DP>(0.0,0.0);
complex<DP> result; complex<DP> result;
result=log(B.chain.Nsites*1.0/4.0); result=log(B.chain.Nsites*1.0/4.0);
int sizeA=0; int sizeA=0;
int sizeB=0; int sizeB=0;
for (int i = 0; i < A.chain.Nstrings; ++i) for (int i = 0; i < A.chain.Nstrings; ++i)
sizeA+=A.base.Nrap[i]*A.chain.Str_L[i]; sizeA+=A.base.Nrap[i]*A.chain.Str_L[i];
for (int i = 0; i < B.chain.Nstrings; ++i) for (int i = 0; i < B.chain.Nstrings; ++i)
sizeB+=B.base.Nrap[i]*B.chain.Str_L[i]; sizeB+=B.base.Nrap[i]*B.chain.Str_L[i];
complex<DP>* mu = new complex<DP>[sizeA]; complex<DP>* mu = new complex<DP>[sizeA];
complex<DP>* lam = new complex<DP>[sizeB]; complex<DP>* lam = new complex<DP>[sizeB];
int index=0; int index=0;
for (int i = 0; i < A.chain.Nstrings; ++i) for (int i = 0; i < A.chain.Nstrings; ++i)
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha) for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
for (int a = 1; a <= A.chain.Str_L[i]; ++a) 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));
mu[index]=(A.lambda[i][alpha] + 0.5 * -eta * (A.chain.Str_L[i] + 1.0 - 2.0 * a)); index++;
index++; }
}
index=0; index=0;
for (int i = 0; i < B.chain.Nstrings; ++i) for (int i = 0; i < B.chain.Nstrings; ++i)
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha) for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
for (int a = 1; a <= B.chain.Str_L[i]; ++a) 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));
lam[index]=(B.lambda[i][alpha] + 0.5 * -eta * (B.chain.Str_L[i] + 1.0 - 2.0 * a)); index++;
index++; }
}
Lambda re_ln_Fn_F_B_0(B.chain, B.base); Lambda re_ln_Fn_F_B_0(B.chain, B.base);
Lambda im_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 re_ln_Fn_G_0(B.chain, B.base);
Lambda im_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 re_ln_Fn_G_2(B.chain, B.base);
Lambda im_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_prod1 = 0.0;
complex<DP> ln_prod2 = 0.0; complex<DP> ln_prod2 = 0.0;
complex<DP> ln_prod3 = 0.0; complex<DP> ln_prod3 = 0.0;
complex<DP> ln_prod4 = 0.0; complex<DP> ln_prod4 = 0.0;
for (int i = 0; i < A.chain.Nstrings; ++i) for (int i = 0; i < A.chain.Nstrings; ++i)
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha) for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
for (int a = 1; a <= A.chain.Str_L[i]; ++a) 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))); 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 i = 0; i < B.chain.Nstrings; ++i)
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha) for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
for (int a = 1; a <= B.chain.Str_L[i]; ++a) 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) 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))); 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... // Define the F ones earlier...
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { 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)); 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)); 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)); 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)); 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)); 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)); im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
}
} }
}
//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!
SQMat_CX Hm(0.0, A.base.Mdown);
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
// for (int i = 0; i < A.chain.Nstrings; ++i) // now define the elements Hm[a][M]
// 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) Hm[index_a][B.base.Mdown] = eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
// for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha) index_a++;
// 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 }}} // sums over j, alpha, a
SQMat_CX matrix(0.0, A.base.Mdown); complex<DP> F= complex<DP>(0.0,0.0);
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:"; complex<DP> detmatrix;
// for(int j=0; j<sizeA;j++){ detmatrix=exp(lndet_LU_CX_dstry(Hm));
// 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]:"; //mu is the ground state!
// for(int j=0; j<sizeA;j++){ //A -> mu, B -> lam
// for(int k=0; k<sizeA;k++) cout<<"BbDa["<<j<<"]["<<k<<"]:"<<BbDa[j][k]<<", "; SQMat_CX G(0.0, A.base.Mdown);
// cout<<endl; SQMat_CX BbDa(0.0, A.base.Mdown);
// } index_a = 0;
// 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; for (int j = 0; j < A.chain.Nstrings; ++j) {
// cout<<"(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G))):"<<(exp(lndet_LU_CX(matrix))-exp(lndet_LU_CX(G)))<<endl; for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
// cout<<"(exp(lndet_LU_CX_dstry(matrix)):"<<(exp(lndet_LU_CX(matrix)))<<endl; for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
//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; index_b = 0;
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; 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);
//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; 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) {
complex<DP> F2=exp(eta*(B.K-A.K))*(-2.0*sum); {
complex<DP> F3=(exp(eta*(B.K-A.K)))*(detmatrix);
F=detmatrix; if (b > 1){
// cout<<"F1:"<<F*sqrt(exp(result))<<" F2:"<<F2*sqrt(exp(result))<<" F3:"<<F3*sqrt(exp(result))<<endl; G[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)
// 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; *exp(ln_Fn_G(A,B,k,beta,b-1))
// 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; *exp(-real(ln_Fn_F(B, k, beta, b - 1)));//.../ prod_l!=k | phi(lam[l]-lam[k]) |
// cout<<"F:"<<(F)<<endl; BbDa[index_a][index_b] =0 ;
// cout<<"Smff:"<<exp(result)*4.0*abs(detmatrix*detmatrix)<<endl; }
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]
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];
complex<DP> sum=prod*(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G)));
complex<DP> F2=exp(eta*(B.K-A.K))*(-2.0*sum);
complex<DP> F3=(exp(eta*(B.K-A.K)))*(detmatrix);
F=detmatrix;
F+=exp(i*(A.K-B.K))*(2.0*sum*(-1.0)+detmatrix); 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+=2.0*log(abs(F));
result-=log(A.chain.Nsites-A.base.Mdown*2+2.0); 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) complex<DP> ln_ME_sq = result;
//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;
delete[] mu;
delete[] lam;
// cout<<"normlam"<<"normmu:"<<(exp(A.lnnorm))<<":"<<(exp(B.lnnorm))<<endl; return(0.5 * ln_ME_sq); // Return ME, not MEsq
// 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 ABACUS } // namespace ABACUS

View File

@ -19,62 +19,62 @@ using namespace ABACUS;
namespace ABACUS { namespace ABACUS {
complex<DP> phi(complex<DP> x){return x;} complex<DP> phi(complex<DP> x){return x;}
complex<DP> a(complex<DP> x){return 1;} 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> 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);} 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) inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{ {
complex<DP> ans = 0.0; complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) { for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) { for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b))) if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta] 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))); + 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
}
} }
} }
return(ans);
} }
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;
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b) for (int j = 0; j < A.chain.Nstrings; ++j) {
{ for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
complex<DP> ans = 0.0; for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
for (int j = 0; j < A.chain.Nstrings; ++j) { ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
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);
} }
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_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b) 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(1.0/((A.lambda[j][alpha] - B.lambda[k][beta] 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 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
* (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)) ))); * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.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){ complex<DP> ln_Szz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B){
//clock_t start_time_local = clock(); //clock_t start_time_local = clock();
@ -83,350 +83,357 @@ inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_
const DP real_dev=1.0e-14; const DP real_dev=1.0e-14;
const DP Diff_ME_Thres=1.e-6; const DP Diff_ME_Thres=1.e-6;
// This function returns the natural log of the S^z operator matrix element. // This function returns the natural log of the S^z operator matrix element.
// The A and B states can contain strings. // The A and B states can contain strings.
// Check that the two states refer to the same XXX_Chain // Check that the two states refer to the same XXX_Chain
if (A.chain != B.chain) ABACUSerror("Incompatible XXX_Chains in Szz matrix element."); if (A.chain != B.chain) ABACUSerror("Incompatible XXX_Chains in Szz matrix element.");
// Check that A and B are compatible: same Mdown // Check that A and B are compatible: same Mdown
if (A.base.Mdown != B.base.Mdown) ABACUSerror("Incompatible Mdown between the two states in Szz matrix element!"); if (A.base.Mdown != B.base.Mdown) ABACUSerror("Incompatible Mdown between the two states in Szz matrix element!");
complex<DP> eta=-II; complex<DP> eta=-II;
complex<DP> ln_prod = complex<DP>(0.0,0.0); complex<DP> ln_prod = complex<DP>(0.0,0.0);
complex<DP> result=-300; complex<DP> result=-300;
complex<DP> prev_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)))));
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);
} }
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;
prev_result=result; // Some convenient arrays
bool real_dev_conv=false;
int dev=-1;
while(!real_dev_conv){
real_dev_conv=true;
//add manualy the ground state value dev++;
//add a delta to the origin of the centered strings
if(zero_string){
real_dev_conv=false;
int sizeA=0; for (int j = 0; j < A.chain.Nstrings; ++j)
int sizeB=0; for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
if(abs(A_origin.lambda[j][alpha])<Zero_Center_Thres)
for (int i = 0; i < A.chain.Nstrings; ++i) A.lambda[j][alpha]=real_dev*pow(10.0,dev);
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) prev_result=result;
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta]; //add manualy the ground state value
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
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{
ABACUSerror("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);
complex<DP> prod=complex<DP>(1.0,0.0); return(0.5 * result); // Return ME, not MEsq
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{
ABACUSerror("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 ABACUS } // namespace ABACUS

View File

@ -30,8 +30,6 @@ namespace ABACUS {
rhomin = rhomin_ref; rhomin = rhomin_ref;
rhomax = rhomax_ref; rhomax = rhomax_ref;
prec = req_prec; prec = req_prec;
//rho_tbl = Vect_DP (Nvals + 1);
//I_tbl = Vect_DP (Nvals + 1);
rho_tbl = new DP[Nvals + 1]; rho_tbl = new DP[Nvals + 1];
I_tbl = new DP[Nvals + 1]; I_tbl = new DP[Nvals + 1];
@ -40,7 +38,6 @@ namespace ABACUS {
for (int i = 0; i <= Nvals ; ++i) { for (int i = 0; i <= Nvals ; ++i) {
rho_tbl[i] = rhomin * pow(alpha, DP(i)); rho_tbl[i] = rhomin * pow(alpha, DP(i));
//I_tbl[i] = I_integral (rho_tbl[i], req_prec);
I_tbl[i] = function (rho_tbl[i], req_prec); I_tbl[i] = function (rho_tbl[i], req_prec);
} }
@ -51,14 +48,11 @@ namespace ABACUS {
DP I_table::Return_val (DP req_rho) { DP I_table::Return_val (DP req_rho) {
//cout << "requesting I of " << req_rho << endl;
DP used_rho = fabs(req_rho); DP used_rho = fabs(req_rho);
if (used_rho < rhomin || used_rho >= rhomax) if (used_rho < rhomin || used_rho >= rhomax)
{ {
cerr << "requesting I of " << setprecision(16) << used_rho << " with rho_min = " << rhomin << endl; cerr << "requesting I of " << setprecision(16) << used_rho << " with rho_min = " << rhomin << endl;
//return (I_integral (used_rho, req_prec));
return (function (used_rho, prec)); return (function (used_rho, prec));
} }
@ -67,7 +61,8 @@ namespace ABACUS {
// Do linear interpolation between values at index and index + 1 // Do linear interpolation between values at index and index + 1
return((rho_tbl[index + 1] - used_rho) * I_tbl[index] + (used_rho - rho_tbl[index]) * I_tbl[index + 1])/(rho_tbl[index + 1] - rho_tbl[index]); return((rho_tbl[index + 1] - used_rho) * I_tbl[index] + (used_rho - rho_tbl[index]) * I_tbl[index + 1])
/(rho_tbl[index + 1] - rho_tbl[index]);
} }
} }
@ -75,7 +70,8 @@ namespace ABACUS {
void I_table::Save () { void I_table::Save () {
stringstream outfile_strstream; stringstream outfile_strstream;
outfile_strstream << "I_rhomin_" << rhomin << "_rhomax_" << rhomax << "_Nvals_" << Nvals << "_prec_" << prec << ".dat"; outfile_strstream << "I_rhomin_" << rhomin << "_rhomax_" << rhomax
<< "_Nvals_" << Nvals << "_prec_" << prec << ".dat";
string outfile_str = outfile_strstream.str(); string outfile_str = outfile_strstream.str();
const char* outfilename = outfile_str.c_str(); const char* outfilename = outfile_str.c_str();
@ -92,7 +88,8 @@ namespace ABACUS {
bool I_table::Load (DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec) { bool I_table::Load (DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec) {
stringstream infile_strstream; stringstream infile_strstream;
infile_strstream << "I_rhomin_" << rhomin_ref << "_rhomax_" << rhomax_ref << "_Nvals_" << Nvals_ref << "_prec_" << req_prec << ".dat"; infile_strstream << "I_rhomin_" << rhomin_ref << "_rhomax_" << rhomax_ref
<< "_Nvals_" << Nvals_ref << "_prec_" << req_prec << ".dat";
string infile_str = infile_strstream.str(); string infile_str = infile_strstream.str();
const char* infilename = infile_str.c_str(); const char* infilename = infile_str.c_str();
@ -105,8 +102,6 @@ namespace ABACUS {
rhomin = rhomin_ref; rhomin = rhomin_ref;
rhomax = rhomax_ref; rhomax = rhomax_ref;
prec = req_prec; prec = req_prec;
//rho_tbl = Vect_DP (Nvals + 1);
//I_tbl = Vect_DP (Nvals + 1);
rho_tbl = new DP[Nvals + 1]; rho_tbl = new DP[Nvals + 1];
I_tbl = new DP[Nvals + 1]; I_tbl = new DP[Nvals + 1];
@ -157,8 +152,6 @@ namespace ABACUS {
DP Integral_table::Return_val (DP req_rho) { DP Integral_table::Return_val (DP req_rho) {
//cout << "requesting I of " << req_rho << endl;
if (req_rho < rhomin || req_rho >= rhomax) if (req_rho < rhomin || req_rho >= rhomax)
{ {
cerr << "Requesting I of " << setprecision(16) << req_rho << " with rho_min = " << rhomin << endl; cerr << "Requesting I of " << setprecision(16) << req_rho << " with rho_min = " << rhomin << endl;
@ -192,10 +185,12 @@ namespace ABACUS {
outfile.close(); outfile.close();
} }
bool Integral_table::Load (const char* filenameprefix, DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec, int max_nr_pts) { bool Integral_table::Load (const char* filenameprefix, DP rhomin_ref, DP rhomax_ref,
int Nvals_ref, DP req_prec, int max_nr_pts) {
stringstream infile_strstream; stringstream infile_strstream;
infile_strstream << "Integral_table_" << filenameprefix << "_rhomin_" << rhomin_ref << "_rhomax_" << rhomax_ref << "_Nvals_" << Nvals_ref << "_prec_" << req_prec << "_maxnrpts_" << max_nr_pts << ".dat"; infile_strstream << "Integral_table_" << filenameprefix << "_rhomin_" << rhomin_ref << "_rhomax_" << rhomax_ref
<< "_Nvals_" << Nvals_ref << "_prec_" << req_prec << "_maxnrpts_" << max_nr_pts << ".dat";
string infile_str = infile_strstream.str(); string infile_str = infile_strstream.str();
const char* infilename = infile_str.c_str(); const char* infilename = infile_str.c_str();
@ -203,7 +198,6 @@ namespace ABACUS {
infile.open(infilename); infile.open(infilename);
if (infile.fail()) { if (infile.fail()) {
//cout << "Failed to load file " << infilename << endl;
return (false); return (false);
} }
@ -238,8 +232,6 @@ namespace ABACUS {
{ {
if (xmax < xmin) return(-Integrate_Riemann (function, args, arg_to_integ, xmax, xmin, Npts)); if (xmax < xmin) return(-Integrate_Riemann (function, args, arg_to_integ, xmax, xmin, Npts));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
DP dx = (xmax - xmin)/Npts; DP dx = (xmax - xmin)/Npts;
DP result = 0.0; DP result = 0.0;
@ -258,8 +250,6 @@ namespace ABACUS {
{ {
if (xmax < xmin) return(-Integrate_Riemann_using_table (function, args, arg_to_integ, Itable, xmax, xmin, Npts)); if (xmax < xmin) return(-Integrate_Riemann_using_table (function, args, arg_to_integ, Itable, xmax, xmin, Npts));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
DP dx = (xmax - xmin)/Npts; DP dx = (xmax - xmin)/Npts;
DP result = 0.0; DP result = 0.0;
@ -279,15 +269,9 @@ namespace ABACUS {
DP Integrate_rec_main (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, DP req_prec, int rec_level, int max_rec_level, DP* f) DP Integrate_rec_main (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, DP req_prec, int rec_level, int max_rec_level, DP* f)
{ {
//cout << "Recursion level " << rec_level << endl;
//cout << "Calling Integrate_rec on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
if (rec_level > max_rec_level) { if (rec_level > max_rec_level) {
//cout << "Warning: integral didn't converge between " << setprecision(10) << xmin << " and " << xmax << endl;
return((xmax - xmin) * (f[0] + f[1] + f[2])/3.0); return((xmax - xmin) * (f[0] + f[1] + f[2])/3.0);
} }
//if (rec_level > 16) ABACUSerror("Recursion level too high in Integrate_rec.");
DP* f1 = new DP[9]; DP* f1 = new DP[9];
@ -313,31 +297,33 @@ namespace ABACUS {
DP I1 = dx * (f1[0] + f1[1] + f1[2]); DP I1 = dx * (f1[0] + f1[1] + f1[2]);
if (fabs(I1 - I1_pre) > req_prec || rec_level < 5) if (fabs(I1 - I1_pre) > req_prec || rec_level < 5)
I1 = Integrate_rec_main (function, args, arg_to_integ, xmin, xmin + 3.0 * dx, req_prec, rec_level + 1, max_rec_level, f1); I1 = Integrate_rec_main (function, args, arg_to_integ, xmin, xmin + 3.0 * dx,
req_prec, rec_level + 1, max_rec_level, f1);
DP I2_pre = 3.0 * dx * f[1]; DP I2_pre = 3.0 * dx * f[1];
DP I2 = dx * (f1[3] + f1[4] + f1[5]); DP I2 = dx * (f1[3] + f1[4] + f1[5]);
if (fabs(I2 - I2_pre) > req_prec || rec_level < 5) if (fabs(I2 - I2_pre) > req_prec || rec_level < 5)
I2 = Integrate_rec_main (function, args, arg_to_integ, xmin + 3.0 * dx, xmin + 6.0 * dx, req_prec, rec_level + 1, max_rec_level, &f1[3]); I2 = Integrate_rec_main (function, args, arg_to_integ, xmin + 3.0 * dx, xmin + 6.0 * dx,
req_prec, rec_level + 1, max_rec_level, &f1[3]);
DP I3_pre = 3.0 * dx * f[2]; DP I3_pre = 3.0 * dx * f[2];
DP I3 = dx * (f1[6] + f1[7] + f1[8]); DP I3 = dx * (f1[6] + f1[7] + f1[8]);
if (fabs(I3 - I3_pre) > req_prec || rec_level < 5) if (fabs(I3 - I3_pre) > req_prec || rec_level < 5)
I3 = Integrate_rec_main (function, args, arg_to_integ, xmin + 6.0 * dx, xmax, req_prec, rec_level + 1, max_rec_level, &f1[6]); I3 = Integrate_rec_main (function, args, arg_to_integ, xmin + 6.0 * dx, xmax,
req_prec, rec_level + 1, max_rec_level, &f1[6]);
delete[] f1; delete[] f1;
return(I1 + I2 + I3); return(I1 + I2 + I3);
} }
DP Integrate_rec (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, DP req_prec, int max_rec_level) DP Integrate_rec (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax,
DP req_prec, int max_rec_level)
{ {
if (xmax < xmin) return(-Integrate_rec(function, args, arg_to_integ, xmax, xmin, req_prec, max_rec_level)); if (xmax < xmin) return(-Integrate_rec(function, args, arg_to_integ, xmax, xmin, req_prec, max_rec_level));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
DP* f = new DP[3]; DP* f = new DP[3];
DP dx = (xmax - xmin)/3.0; DP dx = (xmax - xmin)/3.0;
@ -351,8 +337,6 @@ namespace ABACUS {
DP req_prec_rec = sum_fabs_f > 1.0 ? sum_fabs_f * req_prec : req_prec; DP req_prec_rec = sum_fabs_f > 1.0 ? sum_fabs_f * req_prec : req_prec;
//cout << "In Integrate: sum_fabs_f = " << sum_fabs_f << endl;
DP answer = Integrate_rec_main (function, args, arg_to_integ, xmin, xmax, req_prec_rec, 0, max_rec_level, f); DP answer = Integrate_rec_main (function, args, arg_to_integ, xmin, xmax, req_prec_rec, 0, max_rec_level, f);
delete[] f; delete[] f;
@ -363,15 +347,9 @@ namespace ABACUS {
DP Integrate_rec_main_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, DP Integrate_rec_main_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int rec_level, int max_rec_level, DP* f) DP xmin, DP xmax, DP req_prec, int rec_level, int max_rec_level, DP* f)
{ {
//cout << "Recursion level " << rec_level << endl;
//cout << "Calling Integrate_rec on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
if (rec_level > max_rec_level) { if (rec_level > max_rec_level) {
//cout << "Warning: integral didn't converge between " << setprecision(10) << xmin << " and " << xmax << endl;
return((xmax - xmin) * (f[0] + f[1] + f[2])/3.0); return((xmax - xmin) * (f[0] + f[1] + f[2])/3.0);
} }
//if (rec_level > 16) ABACUSerror("Recursion level too high in Integrate_rec.");
DP* f1 = new DP[9]; DP* f1 = new DP[9];
@ -397,19 +375,22 @@ namespace ABACUS {
DP I1 = dx * (f1[0] + f1[1] + f1[2]); DP I1 = dx * (f1[0] + f1[1] + f1[2]);
if (fabs(I1 - I1_pre) > req_prec || rec_level < 5) if (fabs(I1 - I1_pre) > req_prec || rec_level < 5)
I1 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin, xmin + 3.0 * dx, req_prec, rec_level + 1, max_rec_level, f1); I1 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin, xmin + 3.0 * dx,
req_prec, rec_level + 1, max_rec_level, f1);
DP I2_pre = 3.0 * dx * f[1]; DP I2_pre = 3.0 * dx * f[1];
DP I2 = dx * (f1[3] + f1[4] + f1[5]); DP I2 = dx * (f1[3] + f1[4] + f1[5]);
if (fabs(I2 - I2_pre) > req_prec || rec_level < 5) if (fabs(I2 - I2_pre) > req_prec || rec_level < 5)
I2 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin + 3.0 * dx, xmin + 6.0 * dx, req_prec, rec_level + 1, max_rec_level, &f1[3]); I2 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin + 3.0 * dx, xmin + 6.0 * dx,
req_prec, rec_level + 1, max_rec_level, &f1[3]);
DP I3_pre = 3.0 * dx * f[2]; DP I3_pre = 3.0 * dx * f[2];
DP I3 = dx * (f1[6] + f1[7] + f1[8]); DP I3 = dx * (f1[6] + f1[7] + f1[8]);
if (fabs(I3 - I3_pre) > req_prec || rec_level < 5) if (fabs(I3 - I3_pre) > req_prec || rec_level < 5)
I3 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin + 6.0 * dx, xmax, req_prec, rec_level + 1, max_rec_level, &f1[6]); I3 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin + 6.0 * dx, xmax,
req_prec, rec_level + 1, max_rec_level, &f1[6]);
delete[] f1; delete[] f1;
@ -419,9 +400,8 @@ namespace ABACUS {
DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int max_rec_level) DP xmin, DP xmax, DP req_prec, int max_rec_level)
{ {
if (xmax < xmin) return(-Integrate_rec_using_table (function, args, arg_to_integ, Itable, xmax, xmin, req_prec, max_rec_level)); if (xmax < xmin) return(-Integrate_rec_using_table (function, args, arg_to_integ, Itable, xmax, xmin,
req_prec, max_rec_level));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
DP* f = new DP[3]; DP* f = new DP[3];
DP dx = (xmax - xmin)/3.0; DP dx = (xmax - xmin)/3.0;
@ -436,9 +416,8 @@ namespace ABACUS {
DP req_prec_rec = sum_fabs_f > 1.0 ? sum_fabs_f * req_prec : req_prec; DP req_prec_rec = sum_fabs_f > 1.0 ? sum_fabs_f * req_prec : req_prec;
//cout << "In Integrate: sum_fabs_f = " << sum_fabs_f << endl; DP answer = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin, xmax,
req_prec_rec, 0, max_rec_level, f);
DP answer = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin, xmax, req_prec_rec, 0, max_rec_level, f);
delete[] f; delete[] f;
@ -448,15 +427,9 @@ namespace ABACUS {
DP Integrate_rec_main_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, DP Integrate_rec_main_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int rec_level, int max_rec_level, DP* f, ofstream& outfile) DP xmin, DP xmax, DP req_prec, int rec_level, int max_rec_level, DP* f, ofstream& outfile)
{ {
//cout << "Recursion level " << rec_level << endl;
//cout << "Calling Integrate_rec on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
if (rec_level > max_rec_level) { if (rec_level > max_rec_level) {
//cout << "Warning: integral didn't converge between " << setprecision(10) << xmin << " and " << xmax << endl;
return((xmax - xmin) * (f[0] + f[1] + f[2])/3.0); return((xmax - xmin) * (f[0] + f[1] + f[2])/3.0);
} }
//if (rec_level > 16) ABACUSerror("Recursion level too high in Integrate_rec.");
DP* f1 = new DP[9]; DP* f1 = new DP[9];
@ -464,49 +437,46 @@ namespace ABACUS {
args[arg_to_integ] = xmin + 0.5 * dx; args[arg_to_integ] = xmin + 0.5 * dx;
f1[0] = function (args, Itable); f1[0] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[0] << endl;
outfile << args << "\t" << f1[0] << endl; outfile << args << "\t" << f1[0] << endl;
f1[1] = f[0]; f1[1] = f[0];
args[arg_to_integ] = xmin + 2.5 * dx; args[arg_to_integ] = xmin + 2.5 * dx;
f1[2] = function (args, Itable); f1[2] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[2] << endl;
outfile << args << "\t" << f1[2] << endl; outfile << args << "\t" << f1[2] << endl;
args[arg_to_integ] = xmin + 3.5 * dx; args[arg_to_integ] = xmin + 3.5 * dx;
f1[3] = function (args, Itable); f1[3] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[3] << endl;
outfile << args << "\t" << f1[3] << endl; outfile << args << "\t" << f1[3] << endl;
f1[4] = f[1]; f1[4] = f[1];
args[arg_to_integ] = xmin + 5.5 * dx; args[arg_to_integ] = xmin + 5.5 * dx;
f1[5] = function (args, Itable); f1[5] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[5] << endl;
outfile << args << "\t" << f1[5] << endl; outfile << args << "\t" << f1[5] << endl;
args[arg_to_integ] = xmin + 6.5 * dx; args[arg_to_integ] = xmin + 6.5 * dx;
f1[6] = function (args, Itable); f1[6] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[6] << endl;
outfile << args << "\t" << f1[6] << endl; outfile << args << "\t" << f1[6] << endl;
f1[7] = f[2]; f1[7] = f[2];
args[arg_to_integ] = xmin + 8.5 * dx; args[arg_to_integ] = xmin + 8.5 * dx;
f1[8] = function (args, Itable); f1[8] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[8] << endl;
outfile << args << "\t" << f1[8] << endl; outfile << args << "\t" << f1[8] << endl;
DP I1_pre = 3.0 * dx * f[0]; DP I1_pre = 3.0 * dx * f[0];
DP I1 = dx * (f1[0] + f1[1] + f1[2]); DP I1 = dx * (f1[0] + f1[1] + f1[2]);
if (fabs(I1 - I1_pre) > req_prec || rec_level < 5) if (fabs(I1 - I1_pre) > req_prec || rec_level < 5)
I1 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin, xmin + 3.0 * dx, req_prec, rec_level + 1, max_rec_level, f1, outfile); I1 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin, xmin + 3.0 * dx,
req_prec, rec_level + 1, max_rec_level, f1, outfile);
DP I2_pre = 3.0 * dx * f[1]; DP I2_pre = 3.0 * dx * f[1];
DP I2 = dx * (f1[3] + f1[4] + f1[5]); DP I2 = dx * (f1[3] + f1[4] + f1[5]);
if (fabs(I2 - I2_pre) > req_prec || rec_level < 5) if (fabs(I2 - I2_pre) > req_prec || rec_level < 5)
I2 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin + 3.0 * dx, xmin + 6.0 * dx, req_prec, rec_level + 1, max_rec_level, &f1[3], outfile); I2 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin + 3.0 * dx, xmin + 6.0 * dx,
req_prec, rec_level + 1, max_rec_level, &f1[3], outfile);
DP I3_pre = 3.0 * dx * f[2]; DP I3_pre = 3.0 * dx * f[2];
DP I3 = dx * (f1[6] + f1[7] + f1[8]); DP I3 = dx * (f1[6] + f1[7] + f1[8]);
if (fabs(I3 - I3_pre) > req_prec || rec_level < 5) if (fabs(I3 - I3_pre) > req_prec || rec_level < 5)
I3 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin + 6.0 * dx, xmax, req_prec, rec_level + 1, max_rec_level, &f1[6], outfile); I3 = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin + 6.0 * dx, xmax,
req_prec, rec_level + 1, max_rec_level, &f1[6], outfile);
delete[] f1; delete[] f1;
@ -516,9 +486,8 @@ namespace ABACUS {
DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile) DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile)
{ {
if (xmax < xmin) return(-Integrate_rec_using_table (function, args, arg_to_integ, Itable, xmax, xmin, req_prec, max_rec_level, outfile)); if (xmax < xmin) return(-Integrate_rec_using_table (function, args, arg_to_integ, Itable, xmax, xmin,
req_prec, max_rec_level, outfile));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
DP* f = new DP[3]; DP* f = new DP[3];
DP dx = (xmax - xmin)/3.0; DP dx = (xmax - xmin)/3.0;
@ -528,34 +497,28 @@ namespace ABACUS {
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
args[arg_to_integ] = xmin + (i + 0.5) * dx; args[arg_to_integ] = xmin + (i + 0.5) * dx;
f[i] = function (args, Itable); f[i] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f[i] << endl;
outfile << args << "\t" << f[i] << endl; outfile << args << "\t" << f[i] << endl;
sum_fabs_f += fabs(f[i]); sum_fabs_f += fabs(f[i]);
} }
DP req_prec_rec = sum_fabs_f > 1.0 ? sum_fabs_f * req_prec : req_prec; DP req_prec_rec = sum_fabs_f > 1.0 ? sum_fabs_f * req_prec : req_prec;
//cout << "In Integrate: sum_fabs_f = " << sum_fabs_f << endl; DP answer = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin, xmax,
req_prec_rec, 0, max_rec_level, f, outfile);
DP answer = Integrate_rec_main_using_table (function, args, arg_to_integ, Itable, xmin, xmax, req_prec_rec, 0, max_rec_level, f, outfile);
delete[] f; delete[] f;
return(answer); return(answer);
} }
DP Integrate_rec_main_using_table_and_file (DP (*function) (Vect_DP, I_table, ofstream&), Vect_DP& args, int arg_to_integ, I_table Itable, DP Integrate_rec_main_using_table_and_file (DP (*function) (Vect_DP, I_table, ofstream&),
DP xmin, DP xmax, DP req_prec, int rec_level, int max_rec_level, DP* f, ofstream& outfile) Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int rec_level, int max_rec_level,
DP* f, ofstream& outfile)
{ {
//cout << "Recursion level " << rec_level << endl;
//cout << "Calling Integrate_rec on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
if (rec_level > max_rec_level) { if (rec_level > max_rec_level) {
//cout << "Warning: integral didn't converge between " << setprecision(10) << xmin << " and " << xmax << endl;
return((xmax - xmin) * (f[0] + f[1] + f[2])/3.0); return((xmax - xmin) * (f[0] + f[1] + f[2])/3.0);
} }
//if (rec_level > 16) ABACUSerror("Recursion level too high in Integrate_rec.");
DP* f1 = new DP[9]; DP* f1 = new DP[9];
@ -563,61 +526,58 @@ namespace ABACUS {
args[arg_to_integ] = xmin + 0.5 * dx; args[arg_to_integ] = xmin + 0.5 * dx;
f1[0] = function (args, Itable, outfile); f1[0] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[0] << endl;
outfile << args << "\t" << f1[0] << endl; outfile << args << "\t" << f1[0] << endl;
f1[1] = f[0]; f1[1] = f[0];
args[arg_to_integ] = xmin + 2.5 * dx; args[arg_to_integ] = xmin + 2.5 * dx;
f1[2] = function (args, Itable, outfile); f1[2] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[2] << endl;
outfile << args << "\t" << f1[2] << endl; outfile << args << "\t" << f1[2] << endl;
args[arg_to_integ] = xmin + 3.5 * dx; args[arg_to_integ] = xmin + 3.5 * dx;
f1[3] = function (args, Itable, outfile); f1[3] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[3] << endl;
outfile << args << "\t" << f1[3] << endl; outfile << args << "\t" << f1[3] << endl;
f1[4] = f[1]; f1[4] = f[1];
args[arg_to_integ] = xmin + 5.5 * dx; args[arg_to_integ] = xmin + 5.5 * dx;
f1[5] = function (args, Itable, outfile); f1[5] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[5] << endl;
outfile << args << "\t" << f1[5] << endl; outfile << args << "\t" << f1[5] << endl;
args[arg_to_integ] = xmin + 6.5 * dx; args[arg_to_integ] = xmin + 6.5 * dx;
f1[6] = function (args, Itable, outfile); f1[6] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[6] << endl;
outfile << args << "\t" << f1[6] << endl; outfile << args << "\t" << f1[6] << endl;
f1[7] = f[2]; f1[7] = f[2];
args[arg_to_integ] = xmin + 8.5 * dx; args[arg_to_integ] = xmin + 8.5 * dx;
f1[8] = function (args, Itable, outfile); f1[8] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[8] << endl;
outfile << args << "\t" << f1[8] << endl; outfile << args << "\t" << f1[8] << endl;
DP I1_pre = 3.0 * dx * f[0]; DP I1_pre = 3.0 * dx * f[0];
DP I1 = dx * (f1[0] + f1[1] + f1[2]); DP I1 = dx * (f1[0] + f1[1] + f1[2]);
if (fabs(I1 - I1_pre) > req_prec || rec_level < 5) if (fabs(I1 - I1_pre) > req_prec || rec_level < 5)
I1 = Integrate_rec_main_using_table_and_file (function, args, arg_to_integ, Itable, xmin, xmin + 3.0 * dx, req_prec, rec_level + 1, max_rec_level, f1, outfile); I1 = Integrate_rec_main_using_table_and_file (function, args, arg_to_integ, Itable, xmin, xmin + 3.0 * dx,
req_prec, rec_level + 1, max_rec_level, f1, outfile);
DP I2_pre = 3.0 * dx * f[1]; DP I2_pre = 3.0 * dx * f[1];
DP I2 = dx * (f1[3] + f1[4] + f1[5]); DP I2 = dx * (f1[3] + f1[4] + f1[5]);
if (fabs(I2 - I2_pre) > req_prec || rec_level < 5) if (fabs(I2 - I2_pre) > req_prec || rec_level < 5)
I2 = Integrate_rec_main_using_table_and_file (function, args, arg_to_integ, Itable, xmin + 3.0 * dx, xmin + 6.0 * dx, req_prec, rec_level + 1, max_rec_level, &f1[3], outfile); I2 = Integrate_rec_main_using_table_and_file (function, args, arg_to_integ, Itable, xmin + 3.0 * dx, xmin + 6.0 * dx,
req_prec, rec_level + 1, max_rec_level, &f1[3], outfile);
DP I3_pre = 3.0 * dx * f[2]; DP I3_pre = 3.0 * dx * f[2];
DP I3 = dx * (f1[6] + f1[7] + f1[8]); DP I3 = dx * (f1[6] + f1[7] + f1[8]);
if (fabs(I3 - I3_pre) > req_prec || rec_level < 5) if (fabs(I3 - I3_pre) > req_prec || rec_level < 5)
I3 = Integrate_rec_main_using_table_and_file (function, args, arg_to_integ, Itable, xmin + 6.0 * dx, xmax, req_prec, rec_level + 1, max_rec_level, &f1[6], outfile); I3 = Integrate_rec_main_using_table_and_file (function, args, arg_to_integ, Itable, xmin + 6.0 * dx, xmax,
req_prec, rec_level + 1, max_rec_level, &f1[6], outfile);
delete[] f1; delete[] f1;
return(I1 + I2 + I3); return(I1 + I2 + I3);
} }
DP Integrate_rec_using_table_and_file (DP (*function) (Vect_DP, I_table, ofstream&), Vect_DP& args, int arg_to_integ, I_table Itable, DP Integrate_rec_using_table_and_file (DP (*function) (Vect_DP, I_table, ofstream&), Vect_DP& args, int arg_to_integ,
DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile) I_table Itable, DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile)
{ {
if (xmax < xmin) return(-Integrate_rec_using_table_and_file (function, args, arg_to_integ, Itable, xmax, xmin, req_prec, max_rec_level, outfile)); if (xmax < xmin)
return(-Integrate_rec_using_table_and_file (function, args, arg_to_integ, Itable, xmax, xmin,
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl; req_prec, max_rec_level, outfile));
DP* f = new DP[3]; DP* f = new DP[3];
DP dx = (xmax - xmin)/3.0; DP dx = (xmax - xmin)/3.0;
@ -627,16 +587,14 @@ namespace ABACUS {
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
args[arg_to_integ] = xmin + (i + 0.5) * dx; args[arg_to_integ] = xmin + (i + 0.5) * dx;
f[i] = function (args, Itable, outfile); f[i] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f[i] << endl;
outfile << args << "\t" << f[i] << endl; outfile << args << "\t" << f[i] << endl;
sum_fabs_f += fabs(f[i]); sum_fabs_f += fabs(f[i]);
} }
DP req_prec_rec = sum_fabs_f > 1.0 ? sum_fabs_f * req_prec : req_prec; DP req_prec_rec = sum_fabs_f > 1.0 ? sum_fabs_f * req_prec : req_prec;
//cout << "In Integrate: sum_fabs_f = " << sum_fabs_f << endl; DP answer = Integrate_rec_main_using_table_and_file (function, args, arg_to_integ, Itable, xmin, xmax,
req_prec_rec, 0, max_rec_level, f, outfile);
DP answer = Integrate_rec_main_using_table_and_file (function, args, arg_to_integ, Itable, xmin, xmax, req_prec_rec, 0, max_rec_level, f, outfile);
delete[] f; delete[] f;
@ -645,20 +603,14 @@ namespace ABACUS {
// THESE TWO FUNCTIONS HAVE NOT BEEN TESTED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // THESE TWO FUNCTIONS HAVE NOT BEEN TESTED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
DP Integrate_exp_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, DP Integrate_exp_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ,
DP xmin, DP xmax, DP eta_old, DP req_prec, int rec_level, int max_rec_level, DP* f, ofstream& outfile) I_table Itable, DP xmin, DP xmax, DP eta_old, DP req_prec, int rec_level,
int max_rec_level, DP* f, ofstream& outfile)
{ {
//cout << "Recursion level " << rec_level << endl;
//cout << "Calling Integrate_rec on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
DP dx_over_x_old = 0.5 * (eta_old - 1.0/eta_old); DP dx_over_x_old = 0.5 * (eta_old - 1.0/eta_old);
if (rec_level > max_rec_level) { if (rec_level > max_rec_level) {
//cout << "Warning: integral didn't converge between " << setprecision(10) << xmin << " and " << xmax << endl;
//return((xmax - xmin) * (f[0] + f[1] + f[2])/3.0);
return(dx_over_x_old * xmin * eta_old * (f[0] + eta_old * (f[1] + eta_old * f[2]))); return(dx_over_x_old * xmin * eta_old * (f[0] + eta_old * (f[1] + eta_old * f[2])));
} }
//if (rec_level > 16) ABACUSerror("Recursion level too high in Integrate_rec.");
DP* f1 = new DP[9]; DP* f1 = new DP[9];
DP* x_pts = new DP[9]; DP* x_pts = new DP[9];
@ -695,19 +647,22 @@ namespace ABACUS {
DP I1 = dx_over_x * (x_pts[0] * f1[0] + x_pts[1] * f1[1] + x_pts[2] * f1[2]); DP I1 = dx_over_x * (x_pts[0] * f1[0] + x_pts[1] * f1[1] + x_pts[2] * f1[2]);
if (fabs(I1 - I1_pre) > req_prec || rec_level < 5) if (fabs(I1 - I1_pre) > req_prec || rec_level < 5)
I1 = Integrate_exp_rec_using_table (function, args, arg_to_integ, Itable, xmin, x_pts[2] * eta, eta, req_prec, rec_level + 1, max_rec_level, f1, outfile); I1 = Integrate_exp_rec_using_table (function, args, arg_to_integ, Itable, xmin, x_pts[2] * eta, eta,
req_prec, rec_level + 1, max_rec_level, f1, outfile);
DP I2_pre = dx_over_x_old * x_pts[4] * f1[4]; DP I2_pre = dx_over_x_old * x_pts[4] * f1[4];
DP I2 = dx_over_x * (x_pts[3] * f1[3] + x_pts[4] * f1[4] + x_pts[5] * f1[5]); DP I2 = dx_over_x * (x_pts[3] * f1[3] + x_pts[4] * f1[4] + x_pts[5] * f1[5]);
if (fabs(I2 - I2_pre) > req_prec || rec_level < 5) if (fabs(I2 - I2_pre) > req_prec || rec_level < 5)
I2 = Integrate_exp_rec_using_table (function, args, arg_to_integ, Itable, x_pts[2] * eta, x_pts[5] * eta, eta, req_prec, rec_level + 1, max_rec_level, &f1[3], outfile); I2 = Integrate_exp_rec_using_table (function, args, arg_to_integ, Itable, x_pts[2] * eta, x_pts[5] * eta, eta,
req_prec, rec_level + 1, max_rec_level, &f1[3], outfile);
DP I3_pre = dx_over_x_old * f1[7]; DP I3_pre = dx_over_x_old * f1[7];
DP I3 = dx_over_x * (x_pts[6] * f1[6] + x_pts[7] * f1[7] + x_pts[8] * f1[8]); DP I3 = dx_over_x * (x_pts[6] * f1[6] + x_pts[7] * f1[7] + x_pts[8] * f1[8]);
if (fabs(I3 - I3_pre) > req_prec || rec_level < 5) if (fabs(I3 - I3_pre) > req_prec || rec_level < 5)
I3 = Integrate_exp_rec_using_table (function, args, arg_to_integ, Itable, x_pts[5] * eta, xmax, eta, req_prec, rec_level + 1, max_rec_level, &f1[6], outfile); I3 = Integrate_exp_rec_using_table (function, args, arg_to_integ, Itable, x_pts[5] * eta, xmax, eta,
req_prec, rec_level + 1, max_rec_level, &f1[6], outfile);
delete[] f1; delete[] f1;
@ -715,20 +670,18 @@ namespace ABACUS {
} }
DP Integrate_exp_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, DP Integrate_exp_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile) DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile)
{ {
// This uses an exponential progression of sampling points. // This uses an exponential progression of sampling points.
if (xmin <= 0.0) ABACUSerror("Use xmin > 0.0 in Integrate_exp."); if (xmin <= 0.0) ABACUSerror("Use xmin > 0.0 in Integrate_exp.");
if (xmax <= 0.0) ABACUSerror("Use xmax > 0.0 in Integrate_exp."); if (xmax <= 0.0) ABACUSerror("Use xmax > 0.0 in Integrate_exp.");
if (xmax < xmin) return(-Integrate_exp_using_table (function, args, arg_to_integ, Itable, xmax, xmin, req_prec, max_rec_level, outfile)); if (xmax < xmin) return(-Integrate_exp_using_table (function, args, arg_to_integ, Itable, xmax, xmin,
req_prec, max_rec_level, outfile));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
DP* f = new DP[3]; DP* f = new DP[3];
DP eta = pow(xmax/xmin, 1.0/6.0); DP eta = pow(xmax/xmin, 1.0/6.0);
//DP dx_over_x = 0.5 * (eta - 1.0/eta);
DP sum_fabs_f = 0.0; DP sum_fabs_f = 0.0;
@ -747,9 +700,8 @@ namespace ABACUS {
DP req_prec_rec = sum_fabs_f > 1.0 ? sum_fabs_f * req_prec : req_prec; DP req_prec_rec = sum_fabs_f > 1.0 ? sum_fabs_f * req_prec : req_prec;
//cout << "In Integrate: sum_fabs_f = " << sum_fabs_f << endl; DP answer = Integrate_exp_rec_using_table (function, args, arg_to_integ, Itable, xmin, xmax, eta,
req_prec_rec, 0, max_rec_level, f, outfile);
DP answer = Integrate_exp_rec_using_table (function, args, arg_to_integ, Itable, xmin, xmax, eta, req_prec_rec, 0, max_rec_level, f, outfile);
delete[] f; delete[] f;
@ -761,11 +713,11 @@ namespace ABACUS {
// *********************************** Adaptive Riemann sum (better implementation) ******************************************* // *********************************** Adaptive Riemann sum (better implementation) *******************************************
std::ostream& operator<< (std::ostream& s, const Integral_result& res) std::ostream& operator<< (std::ostream& s, const Integral_result& res)
{ {
s << res.integ_est << "\t" << res.abs_prec << "\t" << res.rel_prec << "\t" << res.n_vals; s << res.integ_est << "\t" << res.abs_prec << "\t" << res.rel_prec << "\t" << res.n_vals;
return(s); return(s);
} }
Integral_data::~Integral_data() Integral_data::~Integral_data()
{ {
@ -803,12 +755,10 @@ namespace ABACUS {
} }
integ_res.rel_prec = integ_res.abs_prec/integ_res.integ_est; integ_res.rel_prec = integ_res.abs_prec/integ_res.integ_est;
//for (int in = 0; in < n_vals; ++in)
//cout << in << "\t" << data[in].x << "\t" << data[in].f << "\t" << data[in].dx << endl;
} }
Integral_data::Integral_data (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, DP xmin_ref, DP xmax_ref) Integral_data::Integral_data (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ,
I_table Itable, DP xmin_ref, DP xmax_ref)
{ {
xmin = xmin_ref; xmin = xmin_ref;
xmax = xmax_ref; xmax = xmax_ref;
@ -838,12 +788,10 @@ namespace ABACUS {
} }
integ_res.rel_prec = integ_res.abs_prec/integ_res.integ_est; integ_res.rel_prec = integ_res.abs_prec/integ_res.integ_est;
//for (int in = 0; in < n_vals; ++in)
//cout << in << "\t" << data[in].x << "\t" << data[in].f << "\t" << data[in].dx << endl;
} }
Integral_data::Integral_data (DP (*function) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ, Integral_table Itable, DP xmin_ref, DP xmax_ref) Integral_data::Integral_data (DP (*function) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ,
Integral_table Itable, DP xmin_ref, DP xmax_ref)
{ {
xmin = xmin_ref; xmin = xmin_ref;
xmax = xmax_ref; xmax = xmax_ref;
@ -873,9 +821,6 @@ namespace ABACUS {
} }
integ_res.rel_prec = integ_res.abs_prec/integ_res.integ_est; integ_res.rel_prec = integ_res.abs_prec/integ_res.integ_est;
//for (int in = 0; in < n_vals; ++in)
//cout << in << "\t" << data[in].x << "\t" << data[in].f << "\t" << data[in].dx << endl;
} }
void Integral_data::Save (ofstream& outfile) void Integral_data::Save (ofstream& outfile)
@ -960,9 +905,12 @@ namespace ABACUS {
args[arg_to_integ] = new_data[index_new + 8].x; args[arg_to_integ] = new_data[index_new + 8].x;
new_data[index_new + 8].f = function(args); new_data[index_new + 8].f = function(args);
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] =
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)); 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 + 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_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 = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3]); new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3]);
new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3 + 1]); new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3 + 1]);
@ -995,7 +943,8 @@ namespace ABACUS {
return; return;
} }
void Integral_data::Improve_estimate (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, int max_nr_pts) void Integral_data::Improve_estimate (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ,
I_table Itable, int max_nr_pts)
{ {
// We generate a max of 3* n_vals points // We generate a max of 3* n_vals points
data_pt* new_data = new data_pt[3* integ_res.n_vals]; data_pt* new_data = new data_pt[3* integ_res.n_vals];
@ -1066,9 +1015,12 @@ namespace ABACUS {
args[arg_to_integ] = new_data[index_new + 8].x; args[arg_to_integ] = new_data[index_new + 8].x;
new_data[index_new + 8].f = function(args, Itable); 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] =
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)); 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 + 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_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 = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3]); new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3]);
new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3 + 1]); new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3 + 1]);
@ -1101,7 +1053,8 @@ namespace ABACUS {
return; return;
} }
void Integral_data::Improve_estimate (DP (*function) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ, Integral_table Itable, int max_nr_pts) void Integral_data::Improve_estimate (DP (*function) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ,
Integral_table Itable, int max_nr_pts)
{ {
// We generate a max of 3* n_vals points // We generate a max of 3* n_vals points
data_pt* new_data = new data_pt[3* integ_res.n_vals]; data_pt* new_data = new data_pt[3* integ_res.n_vals];
@ -1172,9 +1125,12 @@ namespace ABACUS {
args[arg_to_integ] = new_data[index_new + 8].x; args[arg_to_integ] = new_data[index_new + 8].x;
new_data[index_new + 8].f = function(args, Itable); 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] =
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)); 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 + 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_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 = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3]); new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3]);
new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3 + 1]); new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3 + 1]);
@ -1207,35 +1163,31 @@ namespace ABACUS {
return; return;
} }
Integral_result Integrate_optimal (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts) Integral_result Integrate_optimal (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax,
DP req_rel_prec, DP req_abs_prec, int max_nr_pts)
{ {
if (xmax < xmin) ABACUSerror("Use xmax > xmin in Integrate."); if (xmax < xmin) ABACUSerror("Use xmax > xmin in Integrate.");
Integral_data integ_dat (function, args, arg_to_integ, xmin, xmax); Integral_data integ_dat (function, args, arg_to_integ, 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) { 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) {
integ_dat.Improve_estimate (function, args, arg_to_integ, max_nr_pts); integ_dat.Improve_estimate (function, args, arg_to_integ, max_nr_pts);
} }
// REMOVE next four line
//ofstream outfile;
//outfile.open("testoptimal.dat");
//outfile.precision(16);
//integ_dat.Save(outfile);
return(integ_dat.integ_res); return(integ_dat.integ_res);
} }
Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, Integral_result Integrate_optimal_using_table (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) I_table Itable, DP xmin, DP xmax,
DP req_rel_prec, DP req_abs_prec, int max_nr_pts)
{ {
if (xmax < xmin) ABACUSerror("Use xmax > xmin in Integrate."); if (xmax < xmin) ABACUSerror("Use xmax > xmin in Integrate.");
Integral_data integ_dat (function, args, arg_to_integ, Itable, xmin, xmax); 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) { 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) {
integ_dat.Improve_estimate (function, args, arg_to_integ, Itable, max_nr_pts); integ_dat.Improve_estimate (function, args, arg_to_integ, Itable, max_nr_pts);
} }
@ -1243,13 +1195,15 @@ namespace ABACUS {
} }
Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ, Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ,
Integral_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts) Integral_table Itable, DP xmin, DP xmax,
DP req_rel_prec, DP req_abs_prec, int max_nr_pts)
{ {
if (xmax < xmin) ABACUSerror("Use xmax > xmin in Integrate."); if (xmax < xmin) ABACUSerror("Use xmax > xmin in Integrate.");
Integral_data integ_dat (function, args, arg_to_integ, Itable, xmin, xmax); 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) { 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) {
integ_dat.Improve_estimate (function, args, arg_to_integ, Itable, max_nr_pts); integ_dat.Improve_estimate (function, args, arg_to_integ, Itable, max_nr_pts);
} }
@ -1258,13 +1212,15 @@ namespace ABACUS {
} }
Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, Integral_result Integrate_optimal_using_table (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) I_table Itable, DP xmin, DP xmax,
DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile)
{ {
if (xmax < xmin) ABACUSerror("Use xmax > xmin in Integrate."); if (xmax < xmin) ABACUSerror("Use xmax > xmin in Integrate.");
Integral_data integ_dat (function, args, arg_to_integ, Itable, xmin, xmax); 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) { 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) {
integ_dat.Improve_estimate (function, args, arg_to_integ, Itable, max_nr_pts); integ_dat.Improve_estimate (function, args, arg_to_integ, Itable, max_nr_pts);
@ -1280,11 +1236,12 @@ namespace ABACUS {
// *********************************** Adaptive Riemann sum (better implementation) ******************************************* // *********************************** Adaptive Riemann sum (better implementation) *******************************************
std::ostream& operator<< (std::ostream& s, const Integral_result_CX& res) std::ostream& operator<< (std::ostream& s, const Integral_result_CX& res)
{ {
s << real(res.integ_est) << "\t" << imag(res.integ_est) << "\t" << res.abs_prec << "\t" << res.rel_prec << "\t" << res.n_vals; s << real(res.integ_est) << "\t" << imag(res.integ_est) << "\t"
<< res.abs_prec << "\t" << res.rel_prec << "\t" << res.n_vals;
return(s); return(s);
} }
Integral_data_CX::~Integral_data_CX() Integral_data_CX::~Integral_data_CX()
{ {
@ -1292,7 +1249,8 @@ namespace ABACUS {
if (abs_d2f_dx != 0) delete[] abs_d2f_dx; if (abs_d2f_dx != 0) delete[] abs_d2f_dx;
} }
Integral_data_CX::Integral_data_CX (complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin_ref, DP xmax_ref) Integral_data_CX::Integral_data_CX (complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ,
DP xmin_ref, DP xmax_ref)
{ {
xmin = xmin_ref; xmin = xmin_ref;
xmax = xmax_ref; xmax = xmax_ref;
@ -1322,48 +1280,9 @@ namespace ABACUS {
} }
integ_res.rel_prec = integ_res.abs_prec/abs(integ_res.integ_est); integ_res.rel_prec = integ_res.abs_prec/abs(integ_res.integ_est);
//for (int in = 0; in < n_vals; ++in)
//cout << in << "\t" << data[in].x << "\t" << data[in].f << "\t" << data[in].dx << endl;
} }
// No implementation with I_table yet for complex... // No implementation with I_table yet for complex...
/*
Integral_data::Integral_data (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, DP xmin_ref, DP xmax_ref)
{
xmin = xmin_ref;
xmax = xmax_ref;
integ_res.n_vals = 9;
data = new data_pt[integ_res.n_vals];
abs_d2f_dx = new DP[integ_res.n_vals/3];
integ_res.integ_est = 0.0;
// Initialize x, f and dx:
DP dx = (xmax - xmin)/9.0;
for (int i = 0; i < 9; ++i) {
data[i].x = xmin + (i + 0.5) * dx;
args[arg_to_integ] = data[i].x;
data[i].f = function (args, Itable);
data[i].dx = dx;
integ_res.integ_est += data[i].dx * data[i].f;
}
max_abs_d2f_dx = 0.0;
integ_res.abs_prec = 0.0;
for (int j = 0; j < 3; ++j) {
abs_d2f_dx[j] = dx * fabs(data[3*j].f - 2.0 * data[3*j + 1].f + data[3*j + 2].f);
max_abs_d2f_dx = ABACUS::max(max_abs_d2f_dx, abs_d2f_dx[j]);
integ_res.abs_prec += abs_d2f_dx[j];
}
integ_res.rel_prec = integ_res.abs_prec/integ_res.integ_est;
//for (int in = 0; in < n_vals; ++in)
//cout << in << "\t" << data[in].x << "\t" << data[in].f << "\t" << data[in].dx << endl;
}
*/
void Integral_data_CX::Save (ofstream& outfile) void Integral_data_CX::Save (ofstream& outfile)
{ {
// Reset file writing position // Reset file writing position
@ -1482,114 +1401,6 @@ namespace ABACUS {
} }
// No implementation with I_table yet for complex... // No implementation with I_table yet for complex...
/*
void Integral_data::Improve_estimate (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, int max_nr_pts)
{
// We generate a max of 3* n_vals points
data_pt* new_data = new data_pt[3* integ_res.n_vals];
DP* new_abs_d2f_dx = new DP[integ_res.n_vals];
// Check points in batches of 3; if needed, improve
int threei = 0;
int index_new = 0;
int i, j;
integ_res.abs_prec = 0.0;
integ_res.integ_est = 0.0;
DP new_max_abs_d2f_dx = 0.0;
for (i = 0; i < integ_res.n_vals/3; ++i) {
threei = 3 * i;
if (abs_d2f_dx[i] <= 0.1 * max_abs_d2f_dx || index_new + integ_res.n_vals - threei > max_nr_pts) {
// simply transfer the data points into new_data
new_abs_d2f_dx[index_new/3] = abs_d2f_dx[i];
new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3]);
for (j = 0; j < 3; ++j) {
new_data[index_new].x = data[threei + j].x;
new_data[index_new].f = data[threei + j].f;
new_data[index_new].dx = data[threei + j].dx;
integ_res.integ_est += new_data[index_new].dx * new_data[index_new].f;
index_new++;
}
integ_res.abs_prec += abs_d2f_dx[i];
}
else { // create six new entries and transfer the three existing ones
new_data[index_new].dx = 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 = data[threei].x - new_data[index_new].dx;
new_data[index_new + 1].x = data[threei].x;
new_data[index_new + 2].x = data[threei].x + new_data[index_new].dx;
new_data[index_new + 3].x = data[threei + 1].x - new_data[index_new].dx;
new_data[index_new + 4].x = data[threei + 1].x;
new_data[index_new + 5].x = data[threei + 1].x + new_data[index_new].dx;
new_data[index_new + 6].x = data[threei + 2].x - new_data[index_new].dx;
new_data[index_new + 7].x = data[threei + 2].x;
new_data[index_new + 8].x = 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 = 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 = 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 = 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 = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3]);
new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3 + 1]);
new_max_abs_d2f_dx = ABACUS::max(new_max_abs_d2f_dx, new_abs_d2f_dx[index_new/3 + 2]);
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);
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)
integ_res.rel_prec = integ_res.abs_prec/integ_res.integ_est;
integ_res.n_vals = index_new;
delete[] data;
data = new_data;
max_abs_d2f_dx = new_max_abs_d2f_dx;
delete[] abs_d2f_dx;
abs_d2f_dx = new_abs_d2f_dx;
return;
}
*/
Integral_result_CX Integrate_optimal (complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, Integral_result_CX Integrate_optimal (complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax,
DP req_rel_prec, DP req_abs_prec, int max_nr_pts) DP req_rel_prec, DP req_abs_prec, int max_nr_pts)
{ {
@ -1605,43 +1416,5 @@ namespace ABACUS {
return(integ_dat.integ_res); return(integ_dat.integ_res);
} }
// No implementation with I_table yet for complex...
/*
Integral_result Integrate_optimal_using_table (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)
{
if (xmax < xmin) ABACUSerror("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) {
integ_dat.Improve_estimate (function, args, arg_to_integ, Itable, max_nr_pts);
}
return(integ_dat.integ_res);
}
*/
// No implementation with I_table yet for complex...
/*
Integral_result Integrate_optimal_using_table (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) ABACUSerror("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) {
integ_dat.Improve_estimate (function, args, arg_to_integ, Itable, max_nr_pts);
integ_dat.Save (outfile);
}
return(integ_dat.integ_res);
}
*/
} // namespace ABACUS } // namespace ABACUS

View File

@ -19,7 +19,8 @@ using namespace std;
namespace ABACUS { namespace ABACUS {
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) 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. // This function is only ever called by process rank 0.
@ -41,7 +42,8 @@ namespace ABACUS {
threei = 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) { 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 // simply transfer the data points into new_data
new_abs_d2f_dx[index_new/3] = integdat.abs_d2f_dx[i]; new_abs_d2f_dx[index_new/3] = integdat.abs_d2f_dx[i];
@ -128,14 +130,17 @@ namespace ABACUS {
} }
Integral_result Integrate_optimal_par_using_table (MPI_Comm comm, DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, Integral_result Integrate_optimal_par_using_table (MPI_Comm comm, DP (*function) (Vect_DP, I_table),
I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile) 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) ABACUSerror("Use xmax > xmin in Integrate."); if (xmax < xmin) ABACUSerror("Use xmax > xmin in Integrate.");
Integral_data integ_dat (function, args, arg_to_integ, Itable, xmin, xmax); 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) { 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); Improve_estimate_par (comm, integ_dat, function, args, arg_to_integ, Itable, max_nr_pts);