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

このコミットが含まれているのは:
J.-S. Caux 2018-02-10 21:25:24 +01:00
コミット d337885305
75個のファイルの変更2970行の追加4588行の削除

ファイルの表示

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

ファイルの表示

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

ファイルの表示

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

ファイルの表示

@ -8,7 +8,7 @@ Copyright (c) J.-S. Caux.
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)
{
{
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;
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()
{

ファイルの表示

@ -20,7 +20,9 @@ using namespace ABACUS;
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 mu = atof(argv[2]);
@ -30,12 +32,11 @@ int main(int argc, const char* argv[])
bool Save_data = bool(atoi(argv[6]));
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 (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);
return(0);

ファイルの表示

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

ファイルの表示

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

ファイルの表示

@ -26,11 +26,12 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Heis_DSF executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? "
"Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
cout << "int N \t\t\t Length (number of sites) of the system: "
"use positive even integer values only" << endl;
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
//cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
cout << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
@ -44,8 +45,6 @@ int main(int argc, char* argv[])
DP Delta = atof(argv[ctr++]);
int N = atoi(argv[ctr++]);
int M = atoi(argv[ctr++]);
//int iKmin = atoi(argv[5]);
//int iKmax = atoi(argv[6]);
int Max_Secs = atoi(argv[ctr++]);
DP target_sumrule = atof(argv[ctr++]);
bool refine = (atoi(argv[ctr++]) == 1);
@ -53,89 +52,8 @@ int main(int argc, char* argv[])
// We systematically scan over all momentum integers (to avoid problems with Brillouin folding
int iKmin = -1000*N;
int iKmax = 1000*N;
//Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine, 0, 1);
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine);
}
// The argument given is the name of the standard args_Heis_DSF arguments file
/*
if (argc == 2) { // Used an input file to provide the arguments
if (strcmp(argv[1],"help") == 0) { // Output some instructions
cout << "Usage of Heis_DSF executable: " << endl;
cout << endl << "Provide arguments by either using one of the three following options:" << endl << endl;
cout << "1) via an argument file (see the template `args_Heis_DSF' in directory src/EXECS/), for example" << endl << endl;
cout << "Heis_DSF args_Heis_DSF" << endl << endl;
cout << "2) with arguments (for general momenta scan) whichDSF Delta N M iKmin iKmax Max_Secs refine, for example" << endl << endl;
cout << "Heis_DSF z 0.9 100 40 0 50 600 0" << endl << endl;
cout << "3) with arguments (for general momenta scan) whichDSF Delta N M iKneeded Max_Secs refine, for example" << endl << endl;
cout << "Heis_DSF z 0.9 100 40 20 600 0" << endl << endl;
}
else { // read argument file
ifstream argsfile;
argsfile.open(argv[1]);
if (argsfile.fail()) {
cout << argv[1] << endl;
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);
}

ファイルの表示

@ -26,12 +26,14 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Heis_DSF executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? "
"Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
cout << "int N \t\t\t Length (number of sites) of the system: "
"use positive even integer values only" << endl;
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
//cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers "
"defining the AveragingState; used as defaultScanStatename" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
cout << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
@ -45,8 +47,6 @@ int main(int argc, char* argv[])
int N = atoi(argv[ctr++]);
int M = atoi(argv[ctr++]);
char* Ix2filenameprefix = argv[ctr++];
//int iKmin = atoi(argv[5]);
//int iKmax = atoi(argv[6]);
int Max_Secs = atoi(argv[ctr++]);
DP target_sumrule = atof(argv[ctr++]);
bool refine = (atoi(argv[ctr++]) == 1);
@ -81,8 +81,6 @@ int main(int argc, char* argv[])
Ix2_input_file >> Nrap_read[level];
Ix2_read[level] = Vect<int> (Nrap_read[level]);
for (int alpha = 0; alpha < Nrap_read[level]; ++alpha) Ix2_input_file >> Ix2_read[level][alpha];
//cout << "Read level = " << level << "\tNrap_read[level] = " << Nrap_read[level] << endl;
//cout << "\tIx2_read[level] = " << Ix2_read[level] << endl;
} while (Ix2_input_file.peek() != EOF);
// Construct the Averaging State:
@ -95,36 +93,41 @@ int main(int argc, char* argv[])
if (Delta > 0.0 && Delta < 1.0) {
XXZ_Bethe_State AveragingState (chain, base);
for (int il = 0; il < chain.Nstrings; ++il) {
if (Nrap_read[il] > 0) for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
if (Nrap_read[il] > 0) for (int alpha = 0; alpha < Nrap_read[il]; ++alpha)
AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
}
AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
AveragingState.Compute_All(true);
//cout << "AveragingState read from file: " << AveragingState << endl;
// Perform the scan:
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax,
Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
}
else if (Delta == 1.0) {
XXX_Bethe_State AveragingState (chain, base);
for (int il = 0; il < chain.Nstrings; ++il) {
for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
for (int alpha = 0; alpha < Nrap_read[il]; ++alpha)
AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
}
AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
AveragingState.Compute_All(true);
// Perform the scan:
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax,
Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
}
else if (Delta > 1.0) {
XXZ_gpd_Bethe_State AveragingState (chain, base);
for (int il = 0; il < chain.Nstrings; ++il) {
for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
for (int alpha = 0; alpha < Nrap_read[il]; ++alpha)
AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
}
AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
AveragingState.Compute_All(true);
// Perform the scan:
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax,
Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
}
}

ファイルの表示

@ -29,13 +29,16 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Heis_DSF_par executable: " << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting "
"serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: 0 and N" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << endl << "EXAMPLE: " << endl << endl;
cout << "mpiexec -np 8 Heis_DSF_par z 1.0 100 40 0 100 600" << endl << endl;
@ -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
//cout << "rank " << rank << " ready to prepare." << endl;
if (rank == 0)
// Split up thread list into chunks, one per processor
Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors);
//cout << "rank " << rank << " done preparing, ready to scan." << endl;
// Barrier synchronization, to make sure other processes wait for process of rank 0
// to have finished splitting up the thr file into pieces before starting:
MPI_Barrier (MPI::COMM_WORLD);
@ -93,8 +92,6 @@ int main(int argc, char *argv[])
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax,
supercycle_time, target_sumrule, refine, rank, nr_processors);
//cout << "rank " << rank << " finished scanning, reached wrapup stage." << endl;
// Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD);
@ -102,8 +99,6 @@ int main(int argc, char *argv[])
if (rank == 0)
Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors);
//cout << "rank " << rank << " passed wrapup stage." << endl;
// Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD);

ファイルの表示

@ -29,13 +29,17 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Heis_DSF_par_Prepare executable: " << endl;
cout << endl << "This function prepares for 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 << "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 << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: 0 and N" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
@ -65,7 +69,8 @@ int main(int argc, char *argv[])
string defaultScanStatename = "";
// Split up thread list into chunks, one per processor
Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels,
nr_processors_lower_paralevels, nr_processors_at_newlevel);
}

ファイルの表示

@ -29,13 +29,16 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Heis_DSF_par_Run executable: " << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting "
"serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: 0 and N" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
@ -64,9 +67,6 @@ int main(int argc, char *argv[])
}
Max_Secs = 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.");

ファイルの表示

@ -13,7 +13,6 @@ Purpose: Parallel version of ABACUS using MPICH.
***********************************************************/
#include "ABACUS.h"
//#include "mpi.h" // not needed for Prepare or Wrapup
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 << "This function wraps up an ABACUSG parallel mode run." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: 0 and N" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
@ -65,7 +66,8 @@ int main(int argc, char *argv[])
string defaultScanStatename = "";
// Split up thread list into chunks, one per processor
Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels,
nr_processors_lower_paralevels, nr_processors_at_newlevel);
}

ファイルの表示

@ -27,11 +27,9 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_Catalogue_Fixed_c_k_Nscaling executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
//cout << "int Nc \t\t number of steps in interaction value" << endl;
//cout << "int Nstep \t\t\t Steps to be taken in number of particles: use positive integer values only. Filling will be set to 1 (L == N)" << endl;
//cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over (in units of N == Nstep): recommended values: 0 and 2*N" << endl;
cout << "int kfact \t\t momentum factor: momemntum will be set to kfact * kF/4" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
@ -47,11 +45,8 @@ int main(int argc, char* argv[])
DP target_sumrule = atof(argv[ia++]);
int Max_Secs = atoi(argv[ia++]);
//clock_t StartTime = clock();
double StartTime = omp_get_wtime();
//clock_t ActualTime = StartTime;
double ActualTime = omp_get_wtime();
int Secs_left = Max_Secs;
@ -99,7 +94,6 @@ int main(int argc, char* argv[])
ActualTime = omp_get_wtime();
//Secs_left = int(60*Max_minutes - double(ActualTime - StartTime)/CLOCKS_PER_SEC);
Secs_left = int(Max_Secs - (ActualTime - StartTime));
cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl;

ファイルの表示

@ -26,11 +26,13 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
@ -51,9 +53,6 @@ int main(int argc, char* argv[])
DP target_sumrule = atof(argv[9]);
bool refine = (atoi(argv[10]) == 1);
//cout << "target_sumrule = " << target_sumrule << endl;
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine, 0, 1);
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine);
}

ファイルの表示

@ -26,13 +26,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the "
"AveragingState; used as defaultScanStatename" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "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;
@ -49,7 +51,6 @@ int main(int argc, char* argv[])
char* Ix2filenameprefix = argv[n++];
int iKmin = atoi(argv[n++]);
int iKmax = atoi(argv[n++]);
//DP kBT = atof(argv[n++]);
int Max_Secs = atoi(argv[n++]);
DP target_sumrule = atof(argv[n++]);
bool refine = (atoi(argv[n++]) == 1);
@ -70,7 +71,6 @@ int main(int argc, char* argv[])
}
for (int i = 0; i < N; ++i) {
Ix2_input_file >> Ix2_input[i];
//cout << i << "\t" << Ix2_input[i] << endl;
}
// Now define the AveragingState
@ -78,16 +78,6 @@ int main(int argc, char* argv[])
AveragingState.Ix2 = Ix2_input;
AveragingState.Compute_All(true);
//cout << "Averaging state: " << AveragingState << endl;
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine, 0, 1);
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine);
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
// int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors)
// Simplified function call of the above:
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
// int Max_Secs, DP target_sumrule, bool refine)
Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine);
}

ファイルの表示

@ -30,15 +30,18 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_par_Prepare executable: " << endl;
cout << endl << "This function prepares an ABACUS parallel mode run, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "This function prepares an ABACUS parallel mode run, starting from a preexisting "
"serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the "
"AveragingState; used as defaultScanStatename" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
@ -55,7 +58,6 @@ int main(int argc, char *argv[])
Ix2filenameprefix = argv[n++];
iKmin = atoi(argv[n++]);
iKmax = atoi(argv[n++]);
//kBT = atof(argv[n++]);
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
if (argc != 10 + 2*(paralevel - 1)) ABACUSerror("Wrong nr of arguments in LiebLin_DSF_GeneralState_par_Prepare.");
@ -75,28 +77,11 @@ int main(int argc, char *argv[])
stringstream filenamestrstream;
filenamestrstream << Ix2filenameprefix;
string defaultScanStatename = filenamestrstream.str();
/*
filenamestrstream << ".Ix2";
string filenamestr = filenamestrstream.str();
const char* filename_Cstr = filenamestr.c_str();
Ix2_input_file.open(filename_Cstr);
if (Ix2_input_file.fail()) {
cout << filename_Cstr << endl;
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
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);
}

ファイルの表示

@ -30,24 +30,25 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_par executable: " << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting "
"serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the "
"AveragingState; used as defaultScanStatename" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
//cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
return(0);
}
//else { // correct nr of arguments
int n = 1;
whichDSF = *argv[n++];
c_int = atof(argv[n++]);
@ -56,7 +57,6 @@ int main(int argc, char *argv[])
Ix2filenameprefix = argv[n++];
iKmin = atoi(argv[n++]);
iKmax = atoi(argv[n++]);
//kBT = atof(argv[n++]);
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
if (argc != 10 + 2*(paralevel - 1)) ABACUSerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
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++]);
}
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.");
@ -98,7 +94,6 @@ int main(int argc, char *argv[])
}
for (int i = 0; i < N; ++i) {
Ix2_input_file >> Ix2_input[i];
//cout << i << "\t" << Ix2_input[i] << endl;
}
// Now define the AveragingState
@ -126,17 +121,14 @@ int main(int argc, char *argv[])
DP tnow = MPI::Wtime();
//while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
if (Max_Secs_used > 0) {
// Barrier synchronization
MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk !
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
// supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs,
target_sumrule, refine, paralevel, rank, nr_processors);
// Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD);

ファイルの表示

@ -32,13 +32,15 @@ int main(int argc, char *argv[])
cout << endl << "Usage of LiebLin_DSF_par_Wrapup executable: " << endl;
cout << endl << "This function wraps up an ABACUS parallel mode run." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the "
"AveragingState; used as defaultScanStatename" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
@ -55,7 +57,6 @@ int main(int argc, char *argv[])
Ix2filenameprefix = argv[n++];
iKmin = atoi(argv[n++]);
iKmax = atoi(argv[n++]);
//kBT = atof(argv[n++]);
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
if (argc != 10 + 2*(paralevel - 1)) ABACUSerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
@ -73,28 +74,11 @@ int main(int argc, char *argv[])
stringstream filenamestrstream;
filenamestrstream << Ix2filenameprefix;
string defaultScanStatename = filenamestrstream.str();
/*
filenamestrstream << ".Ix2";
string filenamestr = filenamestrstream.str();
const char* filename_Cstr = filenamestr.c_str();
Ix2_input_file.open(filename_Cstr);
if (Ix2_input_file.fail()) {
cout << filename_Cstr << endl;
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:
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);
}

ファイルの表示

@ -26,15 +26,16 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_MosesState executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int 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 << "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;
@ -48,12 +49,10 @@ int main(int argc, char* argv[])
DP L = atof(argv[3]);
int N = atoi(argv[4]);
int Nl = atoi(argv[5]);
//int Nr = N - Nl;
int DIl = atoi(argv[6]);
int DIr = atoi(argv[7]);
int iKmin = atoi(argv[8]);
int iKmax = atoi(argv[9]);
//DP kBT = atof(argv[7]);
int Max_Secs = atoi(argv[10]);
DP target_sumrule = atof(argv[11]);
bool refine = (atoi(argv[12]) == 1);
@ -67,8 +66,6 @@ int main(int argc, char* argv[])
MosesState.Compute_All (true);
//cout << MosesState << endl;
// Handy default name:
stringstream defaultScanStatename_strstream;
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;

ファイルの表示

@ -31,16 +31,19 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_MosesState_par executable: " << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting "
"serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
cout << endl << "EXAMPLE: " << endl << endl;
@ -63,8 +66,6 @@ int main(int argc, char *argv[])
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.");
MPI::Init(argc, argv);
@ -103,7 +104,6 @@ int main(int argc, char *argv[])
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
@ -111,9 +111,8 @@ int main(int argc, char *argv[])
MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk !
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, supercycle_time, target_sumrule, refine, rank, nr_processors);
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time, target_sumrule, refine, rank, nr_processors);
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time,
target_sumrule, refine, rank, nr_processors);
// Another barrier synchronization
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
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

ファイルの表示

@ -31,16 +31,19 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Prepare executable: " << endl;
cout << endl << "This function prepares an ABACUS parallel mode run, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "This function prepares an ABACUS parallel mode run, starting from a preexisting "
"serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
@ -86,7 +89,9 @@ int main(int argc, char *argv[])
// 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);
}

ファイルの表示

@ -31,16 +31,19 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Run executable: " << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting "
"serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
@ -70,9 +73,6 @@ int main(int argc, char *argv[])
}
Max_Secs = 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.");
@ -83,8 +83,6 @@ int main(int argc, char *argv[])
int rank_here = MPI::COMM_WORLD.Get_rank();
int nr_processors_here = MPI::COMM_WORLD.Get_size();
//cout << "rank " << rank_here << " out of " << nr_processors_here << " ready to go." << endl;
Vect<int> rank (paralevel);
Vect<int> nr_processors (paralevel);
for (int i = 0; i < paralevel - 1; ++i) {
@ -117,35 +115,18 @@ int main(int argc, char *argv[])
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
string defaultScanStatename = defaultScanStatename_strstream.str();
//cout << "rank " << rank_here << " out of " << nr_processors_here << " waiting at barrier." << endl;
MPI_Barrier (MPI::COMM_WORLD);
while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
//if (rank == 0)
// Split up thread list into chunks, one per processor
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
// Barrier synchronization, to make sure other processes wait for process of rank 0
// to have finished splitting up the thr file into pieces before starting:
MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk !
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
// Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD);
// Now that everybody is done, digest data into unique files
//if (rank == 0)
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time,
target_sumrule, refine, paralevel, rank, nr_processors);
// Another barrier synchronization
MPI_Barrier (MPI::COMM_WORLD);

ファイルの表示

@ -33,14 +33,16 @@ int main(int argc, char *argv[])
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Wrapup executable: " << endl;
cout << endl << "This function wraps up an ABACUS parallel mode run." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
@ -86,7 +88,9 @@ int main(int argc, char *argv[])
// 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);
}

ファイルの表示

@ -26,15 +26,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
//cout << "int nstates \t\t\t Number of states to be considered in the ensemble" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
//cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
cout << endl << "EXAMPLE: " << endl << endl;
cout << "LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 0.56 10 600 0" << endl << endl;
@ -48,7 +48,6 @@ int main(int argc, char* argv[])
int iKmin = atoi(argv[5]);
int iKmax = atoi(argv[6]);
DP kBT = atof(argv[7]);
//int nstates_req = atoi(argv[8]);
int Max_Secs = atoi(argv[8]);
bool refine = (atoi(argv[9]) == 1);
@ -57,13 +56,11 @@ int main(int argc, char* argv[])
LiebLin_Diagonal_State_Ensemble ensemble;
stringstream ensfilestrstream;
//ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
string ensfilestr = ensfilestrstream.str();
const char* ensfile_Cstr = ensfilestr.c_str();
if (!refine) { // Construct the state ensemble
//ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT, nstates_req);
ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT);
ensemble.Save(ensfile_Cstr); // Save the ensemble
}
@ -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
for (int ns = 0; ns < ensemble.nstates; ++ns) {
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
//int Max_Secs, DP target_sumrule, bool refine, int rank, int nr_processors)
//Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, int(Max_Secs * ensemble.weight[ns]), 1.0e+6, refine, 0, 1);
Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, int(Max_Secs * ensemble.weight[ns]), 1.0e+6, refine);
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

ファイルの表示

@ -27,15 +27,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
//cout << "int nstates \t\t\t Number of states to be considered in the ensemble" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
//cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
cout << endl << "EXAMPLE: " << endl << endl;
cout << "LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 0.56 10 600 0" << endl << endl;
@ -49,7 +49,6 @@ int main(int argc, char* argv[])
int iKmin = atoi(argv[5]);
int iKmax = atoi(argv[6]);
DP kBT = atof(argv[7]);
//int nstates_req = atoi(argv[8]);
int Max_Secs = atoi(argv[8]);
bool refine = (atoi(argv[9]) == 1);
@ -70,13 +69,11 @@ int main(int argc, char* argv[])
LiebLin_Diagonal_State_Ensemble ensemble;
stringstream ensfilestrstream;
//ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
string ensfilestr = ensfilestrstream.str();
const char* ensfile_Cstr = ensfilestr.c_str();
if (!refine) { // Construct the state ensemble
//ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT, nstates_req);
ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT);
ensemble.Save(ensfile_Cstr); // Save the ensemble
}
@ -89,30 +86,6 @@ int main(int argc, char* argv[])
// 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;
DP supercycle_time = 600.0; // allotted time per supercycle
@ -131,7 +104,6 @@ int main(int argc, char* argv[])
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
@ -139,9 +111,6 @@ int main(int argc, char* argv[])
MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk !
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
//supercycle_time, target_sumrule, refine, rank, nr_processors);
Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, supercycle_time, 1.0e+6, refine, rank, nr_processors);
// Another barrier synchronization
@ -150,7 +119,6 @@ int main(int argc, char* argv[])
// 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

ファイルの表示

@ -29,13 +29,16 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_par executable: " << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting "
"serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
@ -57,8 +60,6 @@ int main(int argc, char *argv[])
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.");
MPI::Init(argc, argv);
@ -83,7 +84,6 @@ int main(int argc, char *argv[])
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
@ -91,9 +91,8 @@ int main(int argc, char *argv[])
MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk !
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
supercycle_time, target_sumrule, refine, rank, nr_processors);
supercycle_time, target_sumrule, refine, rank, nr_processors);
// Another barrier synchronization
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
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

ファイルの表示

@ -29,13 +29,16 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_par_Prepare executable: " << endl;
cout << endl << "This function prepares an ABACUS parallel mode run, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "This function prepares an ABACUS parallel mode run, starting from a preexisting "
"serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
@ -67,7 +70,9 @@ int main(int argc, char *argv[])
string defaultScanStatename = "";
// Split up thread list into chunks, one per processor
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
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);
}

ファイルの表示

@ -29,13 +29,16 @@ int main(int argc, char *argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_par_Run executable: " << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "This function runs ABACUS in parallel mode, starting from a preexisting "
"serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
@ -101,7 +104,6 @@ int main(int argc, char *argv[])
MPI_Barrier (MPI::COMM_WORLD);
// then everybody gets going on their own chunk !
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
Max_Secs_used, target_sumrule, refine, paralevel, rank, nr_processors);

ファイルの表示

@ -31,11 +31,13 @@ int main(int argc, char *argv[])
cout << endl << "Usage of LiebLin_DSF_par_Wrapup executable: " << endl;
cout << endl << "This function wraps up an ABACUS parallel mode run." << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int paralevel" << endl;
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
@ -67,7 +69,9 @@ int main(int argc, char *argv[])
string defaultScanStatename = "";
// Digest files into a unique one for the latest paralevel:
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
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);
}

ファイルの表示

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

ファイルの表示

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

ファイルの表示

@ -27,13 +27,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_Data_Daemon executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int_max \t\t Largest value of the interaction parameter: use positive real values only" << endl;
cout << "int Nc \t\t number of steps in interaction value" << endl;
cout << "int cfact \t\t dividing factor (each new interaction value if 1/cfact times the previous)" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int Max_Hrs \t\t Allowed computational time: (in hours)" << endl;
}
@ -52,21 +54,17 @@ int main(int argc, char* argv[])
int Max_Hrs = atoi(argv[ia++]);
// Individual computations are split into chuncks of Max_Hrs/(Nc * 4)
//int Max_Secs = (Max_Hrs * 900)/Nc;
int Max_Secs = (Max_Hrs * 2700)/Nc; // to minimize wrapping up & restarting time
cout << "Data daemon will use chunks of " << Max_Secs << " seconds." << endl;
//clock_t StartTime = clock();
double StartTime = omp_get_wtime();
//clock_t ActualTime = StartTime;
double ActualTime = omp_get_wtime();
DP c_int;
DP target_sumrule = 1.0;
//while (double(ActualTime - StartTime)/CLOCKS_PER_SEC < double(3600 * Max_Hrs - Max_Secs)) {
while (ActualTime - StartTime < double(3600 * Max_Hrs - Max_Secs)) {
Vect<DP> srsat(0.0, Nc);
@ -101,13 +99,12 @@ int main(int argc, char* argv[])
} // for ic
cout << "srsat min found: " << srmin << "\t for c = " << c_int_max/pow(cfact, icmin) << ". Now refining this."
//<< " Time left: " << 3600* Max_Hrs - (ActualTime - StartTime)/CLOCKS_PER_SEC << " seconds." << endl;
<< " Time left: " << 3600* Max_Hrs - (ActualTime - StartTime) << " seconds." << endl;
// Improve the icmin calculation by one chunk:
Scan_LiebLin (whichDSF, c_int_max/pow(cfact, icmin), L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine[icmin]);
Scan_LiebLin (whichDSF, c_int_max/pow(cfact, icmin), L, N, iKmin, iKmax, kBT, Max_Secs,
target_sumrule, refine[icmin]);
//ActualTime = clock();
ActualTime = omp_get_wtime();
} // while there is time

ファイルの表示

@ -27,11 +27,13 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_Data_Daemon_Nscaling executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
//cout << "int Nc \t\t number of steps in interaction value" << endl;
cout << "int Nstep \t\t\t Steps to be taken in number of particles: use positive integer values only. Filling will be set to 1 (L == N)" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over (in units of N == Nstep): recommended values: 0 and 2*N" << endl;
cout << "int Nstep \t\t\t Steps to be taken in number of particles: use positive integer "
"values only. Filling will be set to 1 (L == N)" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over "
"(in units of N == Nstep): recommended values: 0 and 2*N" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
cout << "int Max_minutes \t\t Allowed computational time: (in minutes)" << endl;
@ -48,11 +50,8 @@ int main(int argc, char* argv[])
DP target_sumrule = atof(argv[ia++]);
int Max_minutes = atoi(argv[ia++]);
//clock_t StartTime = clock();
double StartTime = omp_get_wtime();
//clock_t ActualTime = StartTime;
double ActualTime = omp_get_wtime();
int Secs_left = 60* Max_minutes;
@ -91,7 +90,6 @@ int main(int argc, char* argv[])
ActualTime = clock();
//Secs_left = int(60*Max_minutes - double(ActualTime - StartTime)/CLOCKS_PER_SEC);
Secs_left = int(60*Max_minutes - (ActualTime - StartTime));
cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl;

ファイルの表示

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

ファイルの表示

@ -25,7 +25,8 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl;

ファイルの表示

@ -25,12 +25,12 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
//cout << "DP kBT \t\t Temperature" << endl;
cout << "RAW file name" << endl;
cout << "int Npts_t \t Number of points in time for the Fourier transform" << endl;
cout << "DP t_max \t Max time to be used" << endl;
@ -43,7 +43,6 @@ int main(int argc, char* argv[])
int N = atoi(argv[4]);
int iKmin = atoi(argv[5]);
int iKmax = atoi(argv[6]);
//DP kBT = atof(argv[7]);
char* rawfilename = argv[7];
int Npts_t = atoi(argv[8]);
DP t_max = atof(argv[9]);
@ -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.");
ifstream RAW_infile;
//RAW_infile.open(RAW_Cstr);
RAW_infile.open(rawfilename);
if (RAW_infile.fail()) {
//cout << RAW_Cstr << endl;
cout << rawfilename << endl;
ABACUSerror("Could not open RAW_infile... ");
}
@ -74,7 +71,6 @@ int main(int argc, char* argv[])
DP omega;
int iK;
DP FF;
//int conv;
DP dev;
string label;

ファイルの表示

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

ファイルの表示

@ -25,12 +25,12 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
//cout << "DP kBT \t\t Temperature" << endl;
cout << "RAW file name" << endl;
cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
}
@ -42,24 +42,12 @@ int main(int argc, char* argv[])
int N = atoi(argv[4]);
int iKmin = atoi(argv[5]);
int iKmax = atoi(argv[6]);
//DP kBT = atof(argv[7]);
char* rawfilename = argv[7];
int Npts_x = atoi(argv[8]);
// Force Npts_x
//Npts_x = L;
//stringstream filenameprefix;
//Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
//string prefix = filenameprefix.str();
//stringstream RAW_stringstream; string RAW_string;
//RAW_stringstream << prefix << ".raw";
//RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
ifstream RAW_infile;
//RAW_infile.open(RAW_Cstr);
RAW_infile.open(rawfilename);
if (RAW_infile.fail()) {
//cout << RAW_Cstr << endl;
cout << rawfilename << endl;
ABACUSerror("Could not open RAW_infile... ");
}
@ -80,7 +68,6 @@ int main(int argc, char* argv[])
DP omega;
int iK;
DP FF;
//int conv;
DP dev;
string label;
@ -135,7 +122,6 @@ int main(int argc, char* argv[])
// Output to file:
for (int ix = 0; ix < Npts_x; ++ix) {
if (ix > 0) SFT_outfile << endl;
//SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix];
SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix];
}

ファイルの表示

@ -26,7 +26,8 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
@ -41,7 +42,6 @@ int main(int argc, char* argv[])
DP L = atof(argv[3]);
int N = atoi(argv[4]);
int Nl = atoi(argv[5]);
//int Nr = N - Nl;
int DIl = atoi(argv[6]);
int DIr = atoi(argv[7]);
@ -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;
estate.Compute_All(false);
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;
cin >> again;
} while (again != 0);

ファイルの表示

@ -27,11 +27,13 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of LiebLin_RAW_File_Stats executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: -2*N and 2*N" << endl;
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
cout << "int Aggregate size" << endl;
}
@ -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);
DP Chem_Pot = Chemical_Potential (AveragingState);
//DP sumrule_factor = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, fixed_iK, iKneeded);
Vect<DP> sumrule_factor(iKmax - iKmin + 1);
for (int ik = 0; ik < iKmax - iKmin + 1; ++ik)
sumrule_factor[ik] = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, ik, ik);
@ -117,7 +118,8 @@ int main(int argc, char* argv[])
}
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;
maxsrcont = 0.0;
totsrcont = 0.0;

ファイルの表示

@ -19,8 +19,6 @@ using namespace ABACUS;
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");
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 (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);
cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
return(0);

ファイルの表示

@ -19,8 +19,6 @@ using namespace ABACUS;
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");
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 (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);
cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";

ファイルの表示

@ -19,8 +19,8 @@ using namespace ABACUS;
int main(int argc, const char* argv[])
{
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).");
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).");
DP c_int = atof(argv[1]);
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 (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);
cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";

ファイルの表示

@ -26,11 +26,13 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << "Usage of ODSLF_DSF executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"m for S- S+, z for Sz Sz, p for S+ S-." << endl;
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: "
"recommended values: 0 and N" << endl;
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
cout << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
@ -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);
}
else ABACUSerror("Wrong number of arguments to ODSLF_DSF executable.");
return(0);

ファイルの表示

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

ファイルの表示

@ -82,7 +82,8 @@ int main(int argc, char* argv[])
naccounted++;
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;
maxsrcont = 0.0;
totsrcont = 0.0;

ファイルの表示

@ -21,12 +21,10 @@ using namespace ABACUS;
int main(int argc, char* argv[])
{
if (argc != 13 && argc != 14) { // Print out instructions
//if (strcmp(argv[1],"help") == 0) { // Output some instructions
cout << "Usage of Smoothen_Heis_DSF executable: " << endl << endl;
cout << "Provide arguments using one of the following options:" << endl << endl;
cout << "1) (for general momenta) whichDSF Delta N M iKmin iKmax DiK kBT ommin ommax Nom gwidth" << endl << endl;
cout << "2) (for fixed momentum) whichDSF Delta N M iKneeded ommin ommax Nom gwidth" << endl << endl;
//else ABACUSerror("Incomprehensible arguments in Smoothen_Heis_DSF executable.");
}
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);
}

ファイルの表示

@ -25,13 +25,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
cout << "DP kBT \t\t Temperature" << endl;
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; "
"DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
@ -56,7 +58,6 @@ int main(int argc, char* argv[])
DP width = atof(argv[12]);
stringstream filenameprefix;
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
string prefix = filenameprefix.str();
@ -65,15 +66,10 @@ int main(int argc, char* argv[])
Write_K_File (L, iKmin, iKmax);
Write_Omega_File (Nom, ommin, ommax);
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
// We use the scaled width function as default:
// We use the scaled width function as default:
DP sumcheck;
//if (kBT < 0.1)
//sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
}
/*
@ -105,7 +101,5 @@ int main(int argc, char* argv[])
}
*/
//else ABACUSerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
return(0);
}

ファイルの表示

@ -25,14 +25,16 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the "
"AveragingState; used as defaultScanStatename" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
//cout << "DP kBT \t\t Temperature" << endl;
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; "
"DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
@ -51,7 +53,6 @@ int main(int argc, char* argv[])
char* Ix2filenameprefix = argv[n++];
int iKmin = atoi(argv[n++]);
int iKmax = atoi(argv[n++]);
//DP kBT = atof(argv[7]);
DP kBT = 0.0;
int DiK = atoi(argv[n++]);
DP ommin = atof(argv[n++]);
@ -64,8 +65,6 @@ int main(int argc, char* argv[])
string defaultScanStatename = filenamestrstream.str();
stringstream filenameprefix;
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
//Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, defaultScanStatename);
string prefix = filenameprefix.str();
@ -74,15 +73,10 @@ int main(int argc, char* argv[])
Write_K_File (L, iKmin, iKmax);
Write_Omega_File (Nom, ommin, ommax);
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
// We use the scaled width function as default:
// We use the scaled width function as default:
DP sumcheck;
//if (kBT < 0.1)
//sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
}
/*
@ -114,7 +108,5 @@ int main(int argc, char* argv[])
}
*/
//else ABACUSerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
return(0);
}

ファイルの表示

@ -25,7 +25,8 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Smoothen_LiebLin_DSF_MosesState executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl;
@ -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 DIr \t\t shift of right sea as compared to its ground state position" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
//cout << "DP kBT \t\t Temperature" << endl;
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; "
"DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
@ -50,12 +51,10 @@ int main(int argc, char* argv[])
DP L = atof(argv[3]);
int N = atoi(argv[4]);
int Nl = atoi(argv[5]);
//int Nr = N - Nl;
int DIl = atoi(argv[6]);
int DIr = atoi(argv[7]);
int iKmin = atoi(argv[8]);
int iKmax = atoi(argv[9]);
//DP kBT = atof(argv[10]);
DP kBT = 0.0;
int DiK = atoi(argv[10]);
DP ommin = atof(argv[11]);
@ -69,7 +68,6 @@ int main(int argc, char* argv[])
string defaultScanStatename = defaultScanStatename_strstream.str();
stringstream filenameprefix;
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, defaultScanStatename);
string prefix = filenameprefix.str();
@ -80,18 +78,11 @@ int main(int argc, char* argv[])
Write_K_File (L, iKmin, iKmax);
Write_Omega_File (Nom, ommin, ommax);
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
// We use the scaled width function as default:
DP sumcheck;
//if (kBT < 0.1)
//sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
}
//else ABACUSerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
return(0);
}

ファイルの表示

@ -25,13 +25,15 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Smoothen_LiebLin_DSF_Scaled executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
cout << "DP kBT \t\t Temperature" << endl;
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; "
"DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
@ -56,27 +58,18 @@ int main(int argc, char* argv[])
DP width = atof(argv[12]);
stringstream filenameprefix;
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
string prefix = filenameprefix.str();
DP normalization = twoPI * L;
//DP denom_sum_K = L;
Write_K_File (L, iKmin, iKmax);
Write_Omega_File (Nom, ommin, ommax);
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
// We use the scaled width function as default:
DP sumcheck;
//if (kBT < 0.1)
sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
//sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
}
//else ABACUSerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
return(0);
}

ファイルの表示

@ -25,18 +25,18 @@ int main(int argc, char* argv[])
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
cout << endl << "Usage of Smoothen_LiebLin_DSF_over_Ensemble executable: " << endl;
cout << endl << "Provide the following arguments:" << endl << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: "
"d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
cout << "DP L \t\t\t Length of the system" << endl;
cout << "int N \t\t\t Number of particles" << endl;
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
cout << "DP kBT \t\t Temperature" << endl;
//cout << "int nstates \t\t\t Number of states considered in the ensemble" << endl;
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; "
"DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
cout << endl << "EXAMPLE: " << endl << endl;
cout << "Smoothen_LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
@ -50,7 +50,6 @@ int main(int argc, char* argv[])
int iKmin = atoi(argv[5]);
int iKmax = atoi(argv[6]);
DP kBT = atof(argv[7]);
//int nstates_req = atoi(argv[8]);
int DiK = atoi(argv[8]);
DP ommin = atof(argv[9]);
DP ommax = atof(argv[10]);
@ -58,7 +57,6 @@ int main(int argc, char* argv[])
DP width = atof(argv[12]);
stringstream filenameprefix;
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
string prefix = filenameprefix.str();
@ -72,7 +70,6 @@ int main(int argc, char* argv[])
LiebLin_Diagonal_State_Ensemble ensemble;
stringstream ensfilestrstream;
//ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
string ensfilestr = ensfilestrstream.str();
const char* ensfile_Cstr = ensfilestr.c_str();
@ -85,12 +82,10 @@ int main(int argc, char* argv[])
for (int ns = 0; ns < ensemble.nstates; ++ns) {
// Define the raw input file name:
stringstream filenameprefix;
//Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, kBT, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
string prefix = filenameprefix.str();
stringstream RAW_stringstream; string RAW_string;
RAW_stringstream << prefix << ".raw";
//RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
rawfilename[ns] = RAW_stringstream.str();
}

ファイルの表示

@ -21,12 +21,10 @@ using namespace ABACUS;
int main(int argc, char* argv[])
{
if (argc != 10 && argc != 11) { // Print out instructions
//if (strcmp(argv[1],"help") == 0) { // Output some instructions
cout << "Usage of Smoothen_ODSLF_DSF executable: " << endl << endl;
cout << "Provide arguments using one of the following options:" << endl << endl;
cout << "1) (for general momenta) whichDSF Delta N M iKmin iKmax ommin ommax Nom gwidth" << endl << endl;
cout << "2) (for fixed momentum) whichDSF Delta N M iKneeded ommin ommax Nom gwidth" << endl << endl;
//else ABACUSerror("Incomprehensible arguments in Smoothen_ODSLF_DSF executable.");
}
else if (argc == 11) { // !fixed_iK
@ -47,7 +45,8 @@ int main(int argc, char* argv[])
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_Omega_File (Nom, ommin, ommax);
@ -75,7 +74,8 @@ int main(int argc, char* argv[])
int iKmin = 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.");

ファイルの表示

@ -21,7 +21,8 @@ using namespace ABACUS;
int main( int argc, char* argv[])
{
if (!(argc == 3 || argc == 5)) { // provide some info
cout << endl << "This code computes the (1/N) (-1)^j S^z_j on-site staggered magnetization for XXZ_gpd in zero field." << endl;
cout << endl << "This code computes the (1/N) (-1)^j S^z_j on-site staggered magnetization "
"for XXZ_gpd in zero field." << endl;
cout << "First option: provide two arguments: anisotropy Delta (> 1) and system size N (even)." << endl;
cout << "Second option: provide five arguments: system size N (even), Delta min, Delta max, NDelta." << endl;
cout << "The output is Delta, N, stag mag, energy gap." << endl;
@ -57,7 +58,8 @@ int main( int argc, char* argv[])
if (!estate.conv) ABACUSerror("Umklapp 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 (!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;
}
}

ファイルの表示

@ -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) {}
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]),
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)
: J(JJ), Delta(DD), anis(0.0), hz(hh), Nsites(NN), Nstrings(MAXSTRINGS), Str_L(new int[MAXSTRINGS]),
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
@ -43,7 +44,6 @@ namespace ABACUS {
// Set the Str_L and par vectors:
DP gammaoverpi = acos(DD)/PI;
//cout << "gammaoverpi = " << gammaoverpi << endl;
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;
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++;
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
@ -253,86 +249,18 @@ namespace ABACUS {
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
Heis_Base::Heis_Base () : Mdown(0), Nrap(Vect<int>()), Nraptot(0),
Ix2_infty(Vect<DP>()), Ix2_min(Vect<int>()), Ix2_max(Vect<int>()), dimH(0.0), baselabel("") {}
Heis_Base::Heis_Base () : Mdown(0), Nrap(Vect<int>()), Nraptot(0), Ix2_infty(Vect<DP>()),
Ix2_min(Vect<int>()), Ix2_max(Vect<int>()), dimH(0.0), baselabel("") {}
Heis_Base::Heis_Base (const Heis_Base& RefBase) // copy constructor
: 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())),
baselabel(RefBase.baselabel)
Ix2_infty(Vect<DP>(RefBase.Nrap.size())), Ix2_min(Vect<int>(RefBase.Nrap.size())),
Ix2_max(Vect<int>(RefBase.Nrap.size())), baselabel(RefBase.baselabel)
{
for (int i = 0; i < Nrap.size(); ++i) {
Nrap[i] = RefBase.Nrap[i];
@ -344,8 +272,8 @@ namespace ABACUS {
}
Heis_Base::Heis_Base (const Heis_Chain& RefChain, int M)
: Mdown(M), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0),
Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings))
: Mdown(M), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(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;
Nrap[0] = M;
@ -363,20 +291,21 @@ namespace ABACUS {
// Compute dimensionality of this sub-Hilbert space:
complex<double> ln_dimH_cx = 0.0;
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));
}
Heis_Base::Heis_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities)
: Mdown(0), Nrap(Nrapidities), Nraptot(0),
Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings))
: Mdown(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)),
Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings))
{
// 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;
for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
@ -385,33 +314,6 @@ namespace ABACUS {
Nraptot = 0;
for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
/*
// Compute id
id += Nrapidities[0];
long long int factor = 100000LL;
for (int i = 1; i < RefChain.Nstrings; ++i) {
id += factor * Nrapidities[i];
factor *= 100LL;
}
*/
// 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;
M0out << Nrapidities[0];
baselabel = M0out.str();
@ -433,14 +335,15 @@ namespace ABACUS {
// Compute dimensionality of this sub-Hilbert space:
complex<double> ln_dimH_cx = 0.0;
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));
}
Heis_Base::Heis_Base (const Heis_Chain& RefChain, string baselabel_ref)
: Mdown(0), Nrap(Vect<int>(0, RefChain.Nstrings)), Nraptot(0),
Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)),
baselabel (baselabel_ref)
: Mdown(0), Nrap(Vect<int>(0, RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)),
Ix2_min(Vect<int>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)), baselabel (baselabel_ref)
{
// Build Nrapidities vector from baselabel_ref.
// 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_";
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_Base_Label (label_ref);
//cout << "Read data." << endl;
// Initialize Nrap:
for (int i = 0; i < labeldata.type.size(); ++i)
@ -470,7 +371,9 @@ namespace ABACUS {
// Compute dimensionality of this sub-Hilbert space:
complex<double> ln_dimH_cx = 0.0;
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));
}
@ -521,8 +424,9 @@ namespace ABACUS {
sum2 = 0.0;
sum2 += (RefChain.Str_L[j] == RefChain.Str_L[k]) ? 0.0 : 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k])
- 0.5 * fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) * RefChain.anis));
sum2 += (RefChain.Str_L[j] == RefChain.Str_L[k]) ? 0.0 :
2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k])
- 0.5 * fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) * RefChain.anis));
sum2 += 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k])
- 0.5 * (RefChain.Str_L[j] + RefChain.Str_L[k]) * RefChain.anis));
@ -533,8 +437,9 @@ namespace ABACUS {
sum1 += (Nrap[k] - ((j == k) ? 1 : 0)) * sum2;
}
Ix2_infty[j] = (1.0/PI) * fabs(RefChain.Nsites * 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j])
- 0.5 * RefChain.Str_L[j] * RefChain.anis)) - sum1);
Ix2_infty[j] = (1.0/PI) * fabs(RefChain.Nsites *
2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j])
- 0.5 * RefChain.Str_L[j] * RefChain.anis)) - sum1);
} // The Ix2_infty are now set.
@ -576,7 +481,6 @@ namespace ABACUS {
sum1 += Nrap[k] * (2 * ABACUS::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0));
}
//Ix2_infty[j] = (RefChain.Nsites - 1.0 + 2.0 * RefChain.Str_L[j] - sum1);
Ix2_infty[j] = (RefChain.Nsites + 1.0 - sum1); // to get counting right...
} // The Ix2_infty are now set.
@ -644,10 +548,6 @@ namespace ABACUS {
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];
}
@ -665,22 +565,17 @@ namespace ABACUS {
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
//: lambda(Vect<Vect<DP> > (1))
{
lambda[0] = new DP[M];
//lambda[0] = Vect<DP> (M);
for (int j = 0; j < M; ++j) lambda[0][j] = 0.0;
}
Lambda::Lambda (const Heis_Chain& RefChain, const Heis_Base& base)
: 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];
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 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 j = 0; j < Nrap[i]; ++j) lambda[i][j] = RefLambda.lambda[i][j];
}
}
return(*this);
}
@ -722,56 +617,33 @@ namespace ABACUS {
// Function definitions: class Heis_Bethe_State
Heis_Bethe_State::Heis_Bethe_State ()
: chain(Heis_Chain()), base(Heis_Base()), //offsets(Ix2_Offsets()),
//Ix2(Ix2_Config(chain, 1)),
Ix2(Vect<Vect<int> > (1)),
: chain(Heis_Chain()), base(Heis_Base()), 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),
E(0.0), iK(0), K(0.0), lnnorm(-100.0), //base_id(0LL), type_id(0LL), id(0LL), maxid(0LL), nparticles(0)
label("")
E(0.0), iK(0), K(0.0), lnnorm(-100.0), label("")
{
};
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)),
// 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),
: chain(RefState.chain), base(RefState.base), Ix2(RefState.Ix2),
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),
//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)
{
// 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 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];
}
}
//cout << "Heis constructor state OK" << endl;
}
Heis_Bethe_State::Heis_Bethe_State (const Heis_Chain& RefChain, int M)
: chain(RefChain), base(RefChain, M), //offsets(base, 0LL),
//Ix2(Ix2_Config(RefChain, M)),
Ix2 (Vect<Vect<int> > (1)),
: chain(RefChain), base(RefChain, M), Ix2(Vect<Vect<int> > (1)),
lambda(Lambda(RefChain, M)),
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)
//id(0LL), maxid(0LL)
//base_id(0LL), type_id(0LL), id(0LL), maxid(offsets.maxid), nparticles(0)
{
Ix2[0] = Vect<int> (M);
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)
: chain(RefChain), base(RefBase), //offsets(RefBase, 0LL),
//Ix2(Ix2_Config(RefChain, RefBase)),
Ix2 (Vect<Vect<int> > (RefChain.Nstrings)),
: chain(RefChain), base(RefBase), Ix2 (Vect<Vect<int> > (RefChain.Nstrings)),
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)
//id(0LL), maxid(0LL)
//base_id(RefBase.id), type_id(0LL), id(0LL), maxid(offsets.maxid), nparticles(0)
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)
{
// 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;
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.");
@ -812,15 +676,8 @@ namespace ABACUS {
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);
//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;
Vect<Vect<int> > OriginIx2ordered = OriginIx2;
@ -835,26 +692,11 @@ namespace ABACUS {
for (int iexc = 0; iexc < labeldata.nexc[it]; ++iexc)
for (int i = 0; i < labeldata.M[it]; ++i)
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];
//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:
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)
@ -865,11 +707,13 @@ namespace ABACUS {
// (*this) has a base already identical to base of OriginIx2
// 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
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
int ntypes = 1; // level 0 always assumed present
@ -891,7 +735,6 @@ namespace ABACUS {
Vect<Vect<int> > Ix2exc_ref(ntypes);
// Count nr of particle-holes at each level:
//itype = 0;
itype = -1;
for (int il = 0; il < chain.Nstrings; ++il) {
if (il == 0 || base.Nrap[il] > 0) {
@ -932,36 +775,16 @@ namespace ABACUS {
bool symmetric_state = true;
int arg, test1, test3;
//if (chain.Delta <= 1.0) {
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) ? 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;
}
//}
/*
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;
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) ? 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;
}
*/
return symmetric_state;
}
@ -991,8 +814,6 @@ namespace ABACUS {
{
// 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.
Lambda lambda_ref(chain, base);
@ -1001,10 +822,7 @@ namespace ABACUS {
if (reset_rapidities)
(*this).Set_Free_lambdas();
//cout << endl << "After Set_Free_lambdas: " << (*this) << endl;
(*this).Compute_BE();
//cout << endl << "After Compute_BE: " << (*this) << endl;
iter = 0;
iter_Newton = 0;
@ -1037,7 +855,6 @@ namespace ABACUS {
|| straight_improving || extrap_improving || Newton_improving)) {
// 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;
@ -1060,9 +877,9 @@ namespace ABACUS {
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);
straight_improving = (diffsq < diffsq_start);
@ -1115,10 +932,6 @@ namespace ABACUS {
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 (!(straight_improving || extrap_improving || Newton_improving)) {
if (info_findrap) cout << "Before silk gloves: diffsq " << diffsq << endl;
@ -1138,14 +951,9 @@ namespace ABACUS {
// 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;
dev = (*this).String_delta();
//cout << "String delta: " << (*this).String_delta() << "\tBoolean: " << ((*this).String_delta() < HEIS_deltaprec) << endl;
return;
}
@ -1167,7 +975,6 @@ namespace ABACUS {
DP BEleft, BEmid, BEright;
lambda[j][alpha] = lambdaleft;
(*this).Compute_BE (j, alpha);
//cout << "lambda: " << lambda[j][alpha] << "\ttanhlambda: " << tanh(lambda[j][alpha]) << endl;
BEleft= BE[j][alpha];
lambda[j][alpha] = lambdaright;
(*this).Compute_BE (j, alpha);
@ -1175,8 +982,6 @@ namespace ABACUS {
if (BEleft * BEright > 0.0) {
lambda[j][alpha] = lambdajalphastart;
//cout << lambdaleft << "\t" << lambdaright << "\t" << BEleft << "\t" << BEright << endl;
//cout << "Could not bisect BE[" << j << "][" << alpha << "]" << endl;
return;
}
@ -1187,9 +992,6 @@ namespace ABACUS {
(*this).Compute_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
lambdaright = lambdamid;
BEright = BEmid;
@ -1203,16 +1005,12 @@ namespace ABACUS {
else if (BEmid * BEmid < req_prec) return;
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
}
prec_obtained = BEmid * BEmid;
niter_here++;
//cout << "bisect: " << lambdaleft << "\t" << lambdaright << "\t" << BEleft << "\t" << BEright << "\t" << prec_obtained << "\t" << req_prec << endl;
}
return;
@ -1220,15 +1018,10 @@ namespace ABACUS {
void Heis_Bethe_State::Iterate_BAE (DP iter_factor)
{
//DP lambda_old;
for (int j = 0; j < chain.Nstrings; ++j) {
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]);
//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);
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;
// Now begin solving...
@ -1257,16 +1051,14 @@ namespace ABACUS {
while ((diffsq > straight_prec) && (max_iter > iter_done_here)) {
//cout << "BEFORE ITERATION" << endl << (*this) << endl << endl;
(*this).Iterate_BAE(iter_factor);
//cout << "ITERATION " << iter_done_here << endl << (*this) << endl << endl;
iter_done_here++;
}
if ((diffsq > diffsq_ref) || (is_nan(diffsq))) {
// 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 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();
diffsq = diffsq_ref;
}
@ -1281,7 +1073,8 @@ namespace ABACUS {
Lambda lambda_ref(chain, base);
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;
// Now begin solving...
@ -1300,20 +1093,21 @@ namespace ABACUS {
while ((diffsq > extrap_prec) && (max_iter_extrap > iter_done_here)) {
(*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;
(*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;
(*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;
(*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;
//(*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;
@ -1332,11 +1126,8 @@ namespace ABACUS {
rap[1] = lambda2[j][alpha];
rap[2] = lambda3[j][alpha];
rap[3] = lambda4[j][alpha];
//rap[4] = lambda5[j][alpha];
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
@ -1347,7 +1138,8 @@ namespace ABACUS {
if ((diffsq >= diffsq_ref) || (is_nan(diffsq))) {
// 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();
diffsq = diffsq_ref;
}
@ -1365,7 +1157,8 @@ namespace ABACUS {
Lambda lambda_ref(chain, base);
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;
// 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);
iter_done_here++;
//cout << "jmax = " << jmax << "\talphamax = " << alphamax << "\t" << lambda[jmax][alphamax] << "\tBE after " << BE[jmax][alphamax] << endl;
// and reset all important arrays.
(*this).Compute_diffsq();
}
//cout << "Silk gloves: diffsq from " << diffsq_ref << "\tto " << diffsq << endl;
if ((diffsq > diffsq_ref) || (is_nan(diffsq))) {
// 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];
@ -1428,32 +1199,6 @@ namespace ABACUS {
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 ()
{
@ -1465,7 +1210,8 @@ namespace ABACUS {
Vect_INT indx (base.Nraptot);
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);
@ -1488,16 +1234,14 @@ namespace ABACUS {
return;
}
//cout << iter_Newton << "\t" << dlambda << endl;
// 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;
for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) {
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++;
}
@ -1521,12 +1265,14 @@ namespace ABACUS {
{
// 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);
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;
// Now begin solving...
@ -1541,8 +1287,8 @@ namespace ABACUS {
if ((diffsq > diffsq_ref) || (is_nan(diffsq))) {
// 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 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();
diffsq = diffsq_ref;
}
@ -1558,19 +1304,8 @@ namespace ABACUS {
SQMat_CX Gaudin_Red(base.Nraptot);
(*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);
//cout << "Calculated lnnorm = " << lnnorm_check;
//lnnorm = real(lndet_LU_CX_dstry(Gaudin_Red));
lnnorm = real(lnnorm_check);
}
@ -1613,37 +1348,15 @@ namespace ABACUS {
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)
{
// 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.
//cout << "Matching Ix2 for base " << (*this).base.baselabel << " from base " << StateToMatch.base.baselabel << endl;
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.
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;
int nleft = StateToMatch.base.Nrap[il]/2;
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)
if (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;
if (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
//cout << "StateToMatch:" << endl << StateToMatch << endl << "MatchingState:" << endl << (*this) << endl;
}
@ -1679,16 +1393,19 @@ namespace ABACUS {
{
// sends all the state data to output stream
s << endl << "******** Chain with Delta = " << state.chain.Delta << " Nsites = " << state.chain.Nsites << " Mdown = " << state.base.Mdown
//<< ": eigenstate with base_id " << state.base_id << ", type_id " << state.type_id << " id " << state.id << " maxid " << state.maxid << endl
s << endl << "******** Chain with Delta = " << state.chain.Delta
<< " Nsites = " << state.chain.Nsites << " Mdown = " << state.base.Mdown
<< ": eigenstate with label " << state.label << 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) {
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]
<< " Ix2_infty = " << state.base.Ix2_infty[j] << " Ix2_min = " << state.base.Ix2_min[j] << " Ix2_max = " << state.base.Ix2_max[j] << endl;
s << "Type " << j << " Str_L = " << state.chain.Str_L[j] << " par = " << state.chain.par[j]
<< " 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_DP rapidities(state.base.Nrap[j]);
for (int alpha = 0; alpha < state.base.Nrap[j]; ++alpha) {

ファイルの表示

@ -125,19 +125,16 @@ namespace ABACUS {
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
M_found = (HZmin_actual < HZ && HZ <= HZmax_actual);
//cout << "M_actual = " << M_actual << "\tM_step = " << M_step
// << "\tHZmin_actual = " << HZmin_actual << "\tHZmax_actual = " << HZmax_actual << "\tHZ = " << HZ << "\t" << M_found << endl;
}
}
//cout << "M found = " << M_actual << "\tHZmax = " << Ezero[M_actual] - Ezero[M_actual + 1] << "\tHZmin = " << Ezero[M_actual - 1] - Ezero[M_actual] << endl;
return(M_actual);
}
DP Chemical_Potential (const Heis_Bethe_State& AveragingState)
{
return(-H_vs_M (AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown)); // - sign since E_{M+1} - E_M = -H
return(-H_vs_M (AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown));
// - sign since E_{M+1} - E_M = -H
}
}

ファイルの表示

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

ファイルの表示

@ -99,7 +99,6 @@ namespace ABACUS {
else ABACUSerror("Wrong anisotropy in S1_sumrule_factor.");
DP answer = 0.0;
//if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
// Careful for z ! Hamiltonian defined as S^z S^z - 1/4, so add back N/4:
@ -118,8 +117,9 @@ namespace ABACUS {
DP sumrule = 0.0;
if (mporz == 'm' || mporz == 'p') sumrule = - 4.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z + 0.5 * Chem_Pot * 0.5 *(N - 2*M))/N;
//if (mporz == 'm' || mporz == 'p') sumrule = - 1.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * 2.0 * X_x + (Delta - cos((twoPI * iK)/N)) * (X_x + X_z))/N;
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;
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.");
//return(1.0/sumrule);
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 S1_sumrule_factor (char mporz, DP Delta, int N, int M, DP Chem_Pot, DP X_x, DP X_z, int iK)
{
//DP X_x = X_avg ('x', Delta, N, M);
//DP X_z = X_avg ('z', Delta, N, M);
DP sumrule = 0.0;
if (mporz == 'm' || mporz == 'p') sumrule = - 4.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z + 0.5 * Chem_Pot * 0.5 *(N - 2*M))/N;
//if (mporz == 'm' || mporz == 'p') sumrule = - 1.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * 2.0 * X_x + (Delta - cos((twoPI * iK)/N)) * (X_x + X_z))/N;
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;
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.");
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 = 1.0;
//if (!fixed_iK) {
if (iKmin != iKmax) {
if (whichDSF == 'Z') sumrule_factor = 1.0;
else if (whichDSF == 'm')
@ -176,12 +170,11 @@ namespace ABACUS {
else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
}
//else if (fixed_iK) {
else if (iKmin == iKmax) {
if (whichDSF == 'Z') sumrule_factor = 1.0;
else if (whichDSF == 'm' || whichDSF == 'z' || whichDSF == 'p')
//sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, iKneeded);
sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, Chem_Pot, iKmax);
sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites,
AveragingState.base.Mdown, Chem_Pot, iKmax);
else if (whichDSF == 'a') sumrule_factor = 1.0;
else if (whichDSF == 'b') sumrule_factor = 1.0;
else if (whichDSF == 'c') sumrule_factor = 1.0;
@ -190,13 +183,12 @@ namespace ABACUS {
else ABACUSerror("whichDSF option not consistent in Sumrule_Factor");
}
return(sumrule_factor);
}
void Evaluate_F_Sumrule (string prefix, char whichDSF, const Heis_Bethe_State& AveragingState, DP Chem_Pot, int iKmin_ref, int iKmax_ref)
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;
@ -216,18 +208,15 @@ namespace ABACUS {
int iKmod = AveragingState.chain.Nsites;
// We run through the data file to chech the f sumrule at each positive momenta:
//Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);
Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);
DP omega, ME;
int iK, iKexc;
//int conv;
DP dev;
string label;
while (infile.peek() != EOF) {
infile >> omega >> iK >> ME >> dev >> label;
//if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
iKexc = iK;
while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
@ -245,7 +234,9 @@ namespace ABACUS {
for (int i = iKmin; i <= iKmax; ++i) {
if (i > iKmin) outfile << endl;
outfile << i << "\t" << Sum_omega_MEsq[i] * S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, Chem_Pot, X_x, X_z, i);
outfile << 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();

ファイルの表示

@ -126,11 +126,8 @@ namespace ABACUS {
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);
}

ファイルの表示

@ -53,22 +53,12 @@ namespace ABACUS {
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)
{
if (this != &RefState) {
chain = RefState.chain;
base = RefState.base;
//offsets = RefState.offsets;
Ix2 = RefState.Ix2;
lambda = RefState.lambda;
BE = RefState.BE;
@ -80,11 +70,6 @@ namespace ABACUS {
iK = RefState.iK;
K = RefState.K;
lnnorm = RefState.lnnorm;
//base_id = RefState.base_id;
//type_id = RefState.type_id;
//id = RefState.id;
//maxid = RefState.maxid;
//nparticles = RefState.nparticles;
label = RefState.label;
}
return(*this);
@ -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.
bool answer = true;
//int test1, test3;
Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
bool higher_string_on_zero = false;
for (int j = 0; j < chain.Nstrings; ++j) {
// The following line puts answer to true if there is at least one higher string with zero Ix2
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] > 2) && !(chain.Str_L[j] % 2))
higher_string_on_zero = true;
for (int alpha = 0; alpha < base[j]; ++alpha)
if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] > 2) && !(chain.Str_L[j] % 2))
higher_string_on_zero = true;
for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
// NOTE: if base[j] == 0, Zero_at_level[j] remains false.
}
@ -137,18 +122,13 @@ namespace ABACUS {
if (Zero_at_level[j1] && Zero_at_level[j2] && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
string_coincidence = true;
}
/*
bool onep_onem_on_zero = false;
if (option == 'm') { // for Smin, we also exclude symmetric states with 1+ and 1- strings on zero
if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
}
*/
answer = !(symmetric_state && (higher_string_on_zero || string_coincidence /*|| onep_onem_on_zero*/));
// Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
for (int alpha = 0; alpha < base[j]; ++alpha)
if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
if (!answer) {
E = 0.0;
@ -211,123 +191,9 @@ namespace ABACUS {
{
// Returns a new iteration value for lambda[j][alpha] given BE[j][alpha]
return(0.5 * chain.Str_L[j] * tan(0.5 *
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
(2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - BE[j][alpha])
));
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])));
}
/*
void XXX_Bethe_State::Iterate_BAE ()
{
// Recalculates the rapidities by iterating Bethe equations
Lambda New_lambda(chain, base);
DP sumtheta = 0.0;
DP arg = 0.0;
for (int j = 0; j < chain.Nstrings; ++j) {
for (int alpha = 0; alpha < base[j]; ++alpha) {
sumtheta = 0.0;
for (int k = 0; k < chain.Nstrings; ++k) {
for (int beta = 0; beta < base[k]; ++beta)
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
sumtheta += atan(lambda[j][alpha] - lambda[k][beta]);
else sumtheta += 0.5 * Theta_XXX(lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k]);
}
sumtheta *= 2.0;
New_lambda[j][alpha] = 0.5 * chain.Str_L[j] * tan((PI * 0.5 * Ix2[j][alpha] + 0.5 * sumtheta)/chain.Nsites);
}
}
DP New_diffsq = 0.0;
for (int j = 0; j < chain.Nstrings; ++j) {
for (int alpha = 0; alpha < base[j]; ++alpha) {
New_diffsq += pow(New_lambda[j][alpha] - lambda[j][alpha], 2.0);
lambda[j][alpha] = 1.0 * New_lambda[j][alpha] + 0.0 * lambda[j][alpha];
}
}
diffsq = New_diffsq;
iter++;
return;
}
*/
/*
void XXX_Bethe_State::Iterate_BAE_Newton ()
{
// does one step of a Newton method on the rapidities...
Vect_DP RHSBAE (0.0, base.Nraptot); // contains RHS of BAEs
Vect_CX dlambda (0.0, base.Nraptot); // contains delta lambda computed from Newton's method
SQMat_CX Gaudin (0.0, base.Nraptot);
Vect_INT indx (base.Nraptot);
DP sumtheta = 0.0;
DP arg = 0.0;
DP fn_arg = 0.0;
DP olddiffsq = diffsq;
// Compute the RHS of the BAEs:
int index = 0;
for (int j = 0; j < chain.Nstrings; ++j) {
for (int alpha = 0; alpha < base[j]; ++alpha) {
sumtheta = 0.0;
for (int k = 0; k < chain.Nstrings; ++k) {
for (int beta = 0; beta < base[k]; ++beta)
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
sumtheta += atan(lambda[j][alpha] - lambda[k][beta]);
else sumtheta += 0.5 * Theta_XXX((lambda[j][alpha] - lambda[k][beta]), chain.Str_L[j], chain.Str_L[k]);
}
sumtheta *= 2.0;
RHSBAE[index] = chain.Nsites * 2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - sumtheta - PI*Ix2[j][alpha];
index++;
}
}
(*this).Build_Reduced_Gaudin_Matrix (Gaudin);
for (int i = 0; i < base.Nraptot; ++i) dlambda[i] = - RHSBAE[i];
DP d;
ludcmp_CX (Gaudin, indx, d);
lubksb_CX (Gaudin, indx, dlambda);
diffsq = 0.0;
for (int i = 0; i < base.Nraptot; ++i) diffsq += norm(dlambda[i]);
// if we've converged, calculate the norm here, since the work has been done...
if (diffsq < chain.prec) {
lnnorm = 0.0;
for (int j = 0; j < base.Nraptot; j++) lnnorm += log(abs(Gaudin[j][j]));
}
index = 0;
for (int j = 0; j < chain.Nstrings; ++j) {
for (int alpha = 0; alpha < base[j]; ++alpha) {
lambda[j][alpha] += real(dlambda[index]);
index++;
}
}
iter_Newton++;
return;
}
*/
bool XXX_Bethe_State::Check_Rapidities()
{
bool nonan = true;
@ -345,9 +211,8 @@ namespace ABACUS {
DP delta = 0.0;
int occupied_strings = 0;
for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
//if ((*this).conv == 0) delta = 1.0;
for (int i = 0; i < (*this).chain.Nstrings; ++i)
if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
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
log_BAE_reg = DP((*this).chain.Nsites) * log(((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0))
/((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)));
log_BAE_reg = DP((*this).chain.Nsites)
* log(((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0))
/((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)));
for (int k = 0; k < (*this).chain.Nstrings; ++k)
for (int beta = 0; beta < (*this).base[k]; ++beta)
@ -376,15 +242,14 @@ namespace ABACUS {
if ((j != k) || (alpha != beta) || (a != b - 1))
log_BAE_reg += log((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
- ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
) - II );
- ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
) - II );
if ((j != k) || (alpha != beta) || (a != b + 1))
log_BAE_reg -= log(((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
)
- ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
) + II );
log_BAE_reg -= log(((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a))
- ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b))
+ II );
}
// The regular LHS of BAE is now defined. Now sum up the deltas...
@ -432,37 +297,11 @@ namespace ABACUS {
return;
}
/*
void XXX_Bethe_State::Compute_Momentum ()
{
int sum_Ix2 = 0;
DP sum_M = 0.0;
for (int j = 0; j < chain.Nstrings; ++j) {
sum_M += base[j];
for (int alpha = 0; alpha < base[j]; ++alpha) {
sum_Ix2 += Ix2[j][alpha];
}
}
iK = (chain.Nsites/2) * int(sum_M) - (sum_Ix2/2);
while (iK >= chain.Nsites) iK -= chain.Nsites;
while (iK < 0) iK += chain.Nsites;
K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
while (K >= 2.0*PI) K -= 2.0*PI;
while (K < 0.0) K += 2.0*PI;
return;
}
*/
void XXX_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
{
if (Gaudin_Red.size() != base.Nraptot) 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_kbeta;
@ -489,8 +328,8 @@ namespace ABACUS {
}
Gaudin_Red[index_jalpha][index_kbeta]
= complex<DP> ( chain.Nsites * chain.Str_L[j]/(lambda[j][alpha] * lambda[j][alpha] + 0.25 * chain.Str_L[j] * chain.Str_L[j])
- sum_hbar_XXX);
= complex<DP> ( chain.Nsites * chain.Str_L[j]/(lambda[j][alpha] * lambda[j][alpha]
+ 0.25 * chain.Str_L[j] * chain.Str_L[j]) - sum_hbar_XXX);
}
else {
@ -553,25 +392,12 @@ namespace ABACUS {
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)
/ (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));
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)
{
@ -593,7 +419,8 @@ namespace ABACUS {
// and shift quantum numbers by half-integer away from added one:
ReturnState.Ix2[0][RefState.base.Nrap[0]/2] = RefState.Ix2[0][RefState.base.Nrap[0]/2] - 1;
for (int i = 0; i < RefState.base.Nrap[0] + 1; ++i)
ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] = RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)]
= RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
return(ReturnState);
}
@ -617,10 +444,11 @@ namespace ABACUS {
// Remove midmost and shift quantum numbers by half-integer towards removed one:
for (int i = 0; i < RefState.base.Nrap[0]-1; ++i)
ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
ReturnState.Ix2[0][i]
= RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
return(ReturnState);
}
}
} // namespace ABACUS

ファイルの表示

@ -35,12 +35,12 @@ namespace ABACUS {
{};
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))
{
// copy arrays into new ones
//cout << "Calling XXZ state copy constructor." << endl;
for (int j = 0; j < RefState.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < RefState.base[j]; ++j) {
sinhlambda[j][alpha] = RefState.sinhlambda[j][alpha];
@ -48,40 +48,29 @@ namespace ABACUS {
tanhlambda[j][alpha] = RefState.tanhlambda[j][alpha];
}
}
//cout << "Done calling XXZ state copy constructor." << endl;
}
XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, int M)
: Heis_Bethe_State(RefChain, M),
sinhlambda(Lambda(RefChain, M)), coshlambda(Lambda(RefChain, M)), tanhlambda(Lambda(RefChain, M))
{
//cout << "Here in XXZ BS constructor." << endl;
//cout << (*this).lambda[0][0] << endl;
//cout << "OK" << endl;
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) 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, const Heis_Base& RefBase)
: Heis_Bethe_State(RefChain, RefBase),
sinhlambda(Lambda(RefChain, RefBase)), coshlambda(Lambda(RefChain, RefBase)), tanhlambda(Lambda(RefChain, RefBase))
{
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) 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)
{
if (this != &RefState) {
chain = RefState.chain;
base = RefState.base;
//offsets = RefState.offsets;
Ix2 = RefState.Ix2;
lambda = RefState.lambda;
BE = RefState.BE;
@ -93,11 +82,6 @@ namespace ABACUS {
iK = RefState.iK;
K = RefState.K;
lnnorm = RefState.lnnorm;
//base_id = RefState.base_id;
//type_id = RefState.type_id;
//id = RefState.id;
//maxid = RefState.maxid;
//nparticles = RefState.nparticles;
label = RefState.label;
sinhlambda = RefState.sinhlambda;
@ -119,21 +103,16 @@ namespace ABACUS {
for (int alpha = 0; alpha < base[i]; ++alpha) {
if (chain.par[i] == 1) {
//lambda[i][alpha] = atanh(tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites));
x = tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites);
lambda[i][alpha] = atanh(x/sqrt(1.0 + x*x)); // lambda then always initiated real
}
else if (chain.par[i] == -1) {
//lambda[i][alpha] = atanh(-tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis));
x = -tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis);
lambda[i][alpha] = atanh(x/sqrt(1.0 + x*x)); // lambda then always initiated real
}
else 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;
for (int j = 0; j < chain.Nstrings; ++j) {
// The following line puts answer to true if there is at least one higher string with zero Ix2
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] >= 2) /*&& !(chain.Str_L[j] % 2)*/)
higher_string_on_zero = true;
for (int alpha = 0; alpha < base[j]; ++alpha)
if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] >= 2) /*&& !(chain.Str_L[j] % 2)*/)
higher_string_on_zero = true;
for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
// NOTE: if base[j] == 0, Zero_at_level[j] remains false.
}
@ -192,14 +172,16 @@ namespace ABACUS {
bool string_coincidence = false;
for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
if (Zero_at_level[j1] && Zero_at_level[j2] && (chain.par[j1] == chain.par[j2]) && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
if (Zero_at_level[j1] && Zero_at_level[j2] && (chain.par[j1] == chain.par[j2])
&& (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
string_coincidence = true;
}
bool M_odd_and_onep_on_zero = false;
if (option == 'z') { // for Sz, if M is odd, exclude symmetric states with a 1+ on zero
// (zero rapidities in left and right states, so FF det not defined).
bool is_ground_state = base.Nrap[0] == base.Mdown && Ix2[0][0] == -(base.Mdown - 1) && Ix2[0][base.Mdown-1] == base.Mdown - 1;
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;
}
@ -208,12 +190,14 @@ namespace ABACUS {
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)
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) {
E = 0.0;
@ -237,17 +221,23 @@ namespace ABACUS {
for (int beta = 0; beta < base[k]; ++beta) {
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
sumtheta += (chain.par[j] == chain.par[k])
? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
else sumtheta += 0.5 * Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]),
chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])
/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])
/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
else sumtheta += 0.5 * Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])
/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]), chain.Str_L[j],
chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
}
sumtheta *= 2.0;
BE[j][alpha] = ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
: -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
BE[j][alpha] = ((chain.par[j] == 1) ?
2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
:
-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]))
- (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
}
}
void XXZ_Bethe_State::Compute_BE ()
{
@ -265,17 +255,21 @@ namespace ABACUS {
for (int beta = 0; beta < base[k]; ++beta) {
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
sumtheta += (chain.par[j] == chain.par[k])
? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
else sumtheta += 0.5 * Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]),
chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])
/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])
/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
else sumtheta += 0.5 * Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])
/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]), chain.Str_L[j],
chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
}
sumtheta *= 2.0;
BE[j][alpha] = ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
: -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
//if (is_nan(BE[j][alpha])) cout << "BE nan: " << j << "\t" << alpha << "\t" << lambda[j][alpha] << "\t" << tanhlambda[j][alpha] << endl;
BE[j][alpha] = ((chain.par[j] == 1) ?
2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
:
-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]))
- (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
}
}
@ -288,15 +282,14 @@ namespace ABACUS {
DP arg = 0.0;
if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]]
* tan(0.5 *
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
(2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha])
);
* tan(0.5 *
(2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha])
);
else if (chain.par[j] == -1) arg = -tan(0.5 *
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites)
(-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha]))
/chain.ta_n_anis_over_2[chain.Str_L[j]];
(-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])
- BE[j][alpha]))
/chain.ta_n_anis_over_2[chain.Str_L[j]];
if (fabs(arg) < 1.0) {
new_lambda = atanh(arg);
@ -316,15 +309,20 @@ namespace ABACUS {
for (int beta = 0; beta < base[k]; ++beta)
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
sumtheta += (chain.par[j] == chain.par[k])
? atan((new_tanhlambda - tanhlambda[k][beta])/((1.0 - new_tanhlambda * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
: - atan(((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
else sumtheta += 0.5 * Theta_XXZ((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta]),
chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
? atan((new_tanhlambda - tanhlambda[k][beta])
/((1.0 - new_tanhlambda * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
: - atan(((new_tanhlambda - tanhlambda[k][beta])
/(1.0 - new_tanhlambda * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
else sumtheta += 0.5 * Theta_XXZ((new_tanhlambda - tanhlambda[k][beta])
/(1.0 - new_tanhlambda * tanhlambda[k][beta]), chain.Str_L[j],
chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
}
sumtheta *= 2.0;
if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(0.5 * (PI * Ix2[j][alpha] + sumtheta)/chain.Nsites);
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.");
@ -334,7 +332,6 @@ namespace ABACUS {
new_lambda = atanh(arg);
}
//else cout << "Rapidity blows up !\t" << lambda[j][alpha] << "\t" << new_lambda << endl;
} // else
return(new_lambda);
@ -357,9 +354,8 @@ namespace ABACUS {
DP delta = 0.0;
int occupied_strings = 0;
for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
//if ((*this).conv == 0) delta = 1.0;
for (int i = 0; i < (*this).chain.Nstrings; ++i)
if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
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
log_BAE_reg = DP((*this).chain.Nsites) * log(sinh((*this).lambda[j][alpha]
+ 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0)
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
/sinh((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j])));
log_BAE_reg = DP((*this).chain.Nsites)
* log(sinh((*this).lambda[j][alpha]
+ 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0)
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
/sinh((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis
* ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j])));
for (int k = 0; k < (*this).chain.Nstrings; ++k)
for (int beta = 0; beta < (*this).base[k]; ++beta)
for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
if ((j != k) || (alpha != beta) || (a != b - 1))
log_BAE_reg += log(sinh(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
+ 0.25 * II * PI * (1.0 - (*this).chain.par[k])) - II * (*this).chain.anis));
log_BAE_reg += log(sinh(((*this).lambda[j][alpha]
+ 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
- ((*this).lambda[k][beta]
+ 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
+ 0.25 * II * PI * (1.0 - (*this).chain.par[k])) - II * (*this).chain.anis));
if ((j != k) || (alpha != beta) || (a != b + 1))
log_BAE_reg -= log(sinh(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
+ 0.25 * II * PI * (1.0 - (*this).chain.par[k])) + II * (*this).chain.anis));
log_BAE_reg -= log(sinh(((*this).lambda[j][alpha]
+ 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
- ((*this).lambda[k][beta]
+ 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
+ 0.25 * II * PI * (1.0 - (*this).chain.par[k])) + II * (*this).chain.anis));
}
// The regular LHS of BAE is now defined. Now sum up the deltas...
@ -437,7 +439,8 @@ namespace ABACUS {
for (int j = 0; j < chain.Nstrings; ++j) {
for (int alpha = 0; alpha < base[j]; ++alpha) {
sum += sin(chain.Str_L[j] * chain.anis) / (chain.par[j] * cosh(2.0 * lambda[j][alpha]) - cos(chain.Str_L[j] * chain.anis));
sum += 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;
}
/*
void XXZ_Bethe_State::Compute_Momentum ()
{
int sum_Ix2 = 0;
DP sum_M = 0.0;
for (int j = 0; j < chain.Nstrings; ++j) {
sum_M += 0.5 * (1.0 + chain.par[j]) * base[j];
for (int alpha = 0; alpha < base[j]; ++alpha) {
sum_Ix2 += Ix2[j][alpha];
}
}
iK = (chain.Nsites/2) * int(sum_M + 0.1) - (sum_Ix2/2); // + 0.1: for safety...
while (iK >= chain.Nsites) iK -= chain.Nsites;
while (iK < 0) iK += chain.Nsites;
K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
while (K >= 2.0*PI) K -= 2.0*PI;
while (K < 0.0) K += 2.0*PI;
return;
}
*/
void XXZ_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
{
if (Gaudin_Red.size() != base.Nraptot) 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_kbeta;
@ -504,13 +482,14 @@ namespace ABACUS {
for (int betap = 0; betap < base[kp]; ++betap) {
if (!((j == kp) && (alpha == betap)))
sum_hbar_XXZ
+= ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp], chain.par[j], chain.par[kp],
chain.si_n_anis_over_2);
+= ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j],
chain.Str_L[kp], chain.par[j], chain.par[kp], chain.si_n_anis_over_2);
}
}
Gaudin_Red[index_jalpha][index_kbeta]
= complex<DP> ( chain.Nsites * hbar_XXZ (lambda[j][alpha], chain.Str_L[j], chain.par[j], chain.si_n_anis_over_2) - sum_hbar_XXZ);
= 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 {
@ -518,12 +497,13 @@ namespace ABACUS {
Gaudin_Red[index_jalpha][index_kbeta] =
complex<DP> ((chain.par[j] * chain.par[k] == 1)
? chain.si_n_anis_over_2[4]/(pow(sinhlambda[j][alpha] * coshlambda[k][beta]
- coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq)
- coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq)
: chain.si_n_anis_over_2[4]/(-pow(coshlambda[j][alpha] * coshlambda[k][beta]
- sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) );
- sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) );
else
Gaudin_Red[index_jalpha][index_kbeta] = complex<DP> (ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k],
chain.par[j], chain.par[k], chain.si_n_anis_over_2));
Gaudin_Red[index_jalpha][index_kbeta]
= complex<DP> (ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k],
chain.par[j], chain.par[k], chain.si_n_anis_over_2));
}
index_kbeta++;
}
@ -561,7 +541,8 @@ namespace ABACUS {
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]);
}
@ -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);
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);
@ -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);
return(ReturnState);
}
}
} // namespace ABACUS

ファイルの表示

@ -64,20 +64,12 @@ namespace ABACUS {
{
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)
{
if (this != &RefState) {
chain = RefState.chain;
base = RefState.base;
//offsets = RefState.offsets;
Ix2 = RefState.Ix2;
lambda = RefState.lambda;
BE = RefState.BE;
@ -89,11 +81,6 @@ namespace ABACUS {
iK = RefState.iK;
K = RefState.K;
lnnorm = RefState.lnnorm;
//base_id = RefState.base_id;
//type_id = RefState.type_id;
//id = RefState.id;
//maxid = RefState.maxid;
//nparticles = RefState.nparticles;
label = RefState.label;
sinlambda = RefState.sinlambda;
@ -146,7 +133,6 @@ namespace ABACUS {
for (int alpha = 0; alpha < base[j]; ++alpha) {
tanlambda[j][alpha] = tan(lambda[j][alpha]);
//if (lambda[j][alpha] > 0.5*PI) cout << "Rapidity higher than 0.5*PI: j = " << j << "\talpha = " << alpha << "\trap = " << lambda[j][alpha] << "\ttan = " << tanlambda[j][alpha] << endl;
}
}
return;
@ -161,75 +147,6 @@ namespace ABACUS {
bool answer = true;
Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
/*
Vect<bool> min_Ix2_max_busy(false, chain.Nstrings);
Vect<bool> plus_Ix2_max_busy(false, chain.Nstrings);
for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) {
if (Ix2[j][alpha] == -base.Ix2_max[j]) min_Ix2_max_busy[j] = true;
if (Ix2[j][alpha] == base.Ix2_max[j]) plus_Ix2_max_busy[j] = true;
}
*/
/*
// State is not admissible if this is false: -N/2 + 1 \leq \sum I^j_{\alpha} \leq N
int sum_all_Ix2 = 0;
for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) {
sum_all_Ix2 += Ix2[j][alpha];
}
if (sum_all_Ix2 > chain.Nsites || sum_all_Ix2 <= -chain.Nsites) {
cout << "\tSum Ix2 out of fundamental interval: sum_all_Ix2 = " << sum_all_Ix2 << "\tfor N = " << chain.Nsites << endl;
return(false);
}
*/
//Deactivated 2014 06 11, put in Heis_Form_Factor_Entry.cc
/*
// State is not admissible if I_max > 1/2 (N - \sum_k t_{jk} M_k) or I_min < -1/2 (N - sum_k...) + 1 at any level:
int sum1 = 0;
for (int j = 0; j < chain.Nstrings; ++j) {
sum1 = 0;
for (int k = 0; k < chain.Nstrings; ++k) {
sum1 += base[k] * (2 * 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
// 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)
@ -242,7 +159,7 @@ namespace ABACUS {
for (int j = 0; j < chain.Nstrings; ++j) {
// The following line puts answer to true if there is at least one higher string with zero Ix2
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] > 2) /*&& !(chain.Str_L[j] % 2)*/)
higher_string_on_zero = true;
higher_string_on_zero = true;
for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
// NOTE: if base[j] == 0, Zero_at_level[j] remains false.
}
@ -262,8 +179,6 @@ namespace ABACUS {
//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));
@ -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)
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) {
E = 0.0;
@ -300,14 +216,15 @@ namespace ABACUS {
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]))
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]),
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);
+ 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;
@ -331,14 +248,15 @@ namespace ABACUS {
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]))
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]),
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);
+ 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;
@ -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]])
+ PI * floor(0.5 + lambda[j][alpha]/PI)) - BE[j][alpha]);
DP arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(
arg0
//0.5 *
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
//(2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
// + PI * floor(0.5 + lambda[j][alpha]/PI)) - BE[j][alpha])
);
DP arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(arg0);
return(atan(arg)
//+ PI * floor(0.5 + arg0)
//0.5 * (Ix2[j][alpha] + sumtheta/PI)/(chain.Nsites)
+ PI * floor(0.5 + arg0/PI)
);
return(atan(arg) + 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 nonan = true;
for (int j = 0; j < chain.Nstrings; ++j)
for (int alpha = 0; alpha < base[j]; ++alpha) if (nonan) nonan = ((!is_nan(lambda[j][alpha]))
//&& (lambda[j][alpha] > -0.5*PI*chain.Str_L[j])
//&& (lambda[j][alpha] <= 0.5*PI*chain.Str_L[j])
);
for (int alpha = 0; alpha < base[j]; ++alpha)
if (nonan) nonan = ((!is_nan(lambda[j][alpha])));
bool all_within_pi_interval = true;
DP min_lambda = 10.0;
@ -544,9 +311,8 @@ namespace ABACUS {
DP delta = 0.0;
int occupied_strings = 0;
for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
//if ((*this).conv == 0) delta = 1.0;
for (int i = 0; i < (*this).chain.Nstrings; ++i)
if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
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
log_BAE_reg = DP((*this).chain.Nsites) * log(sin((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis
* ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0))
/sin((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)));
* ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0))
/sin((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis
* ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)));
for (int k = 0; k < (*this).chain.Nstrings; ++k)
for (int beta = 0; beta < (*this).base[k]; ++beta)
@ -576,13 +343,13 @@ namespace ABACUS {
if ((j != k) || (alpha != beta) || (a != b - 1))
log_BAE_reg += log(sin(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a ))
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ))
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ))
- II * (*this).chain.anis));
if ((j != k) || (alpha != beta) || (a != b + 1))
log_BAE_reg -= log(sin(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a ))
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ))
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ))
+ II * (*this).chain.anis));
}
@ -631,32 +398,6 @@ namespace ABACUS {
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)
{
@ -689,7 +430,7 @@ namespace ABACUS {
if (!((j == kp) && (alpha == betap)))
sum_hbar_XXZ
+= ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp],
chain.si_n_anis_over_2);
chain.si_n_anis_over_2);
}
}
@ -701,7 +442,7 @@ namespace ABACUS {
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
Gaudin_Red[index_jalpha][index_kbeta] =
complex<DP> (chain.si_n_anis_over_2[4]/(pow(sinlambda[j][alpha] * coslambda[k][beta]
- coslambda[j][alpha] * sinlambda[k][beta], 2.0) + sinhetasq));
- coslambda[j][alpha] * sinlambda[k][beta], 2.0) + sinhetasq));
else
Gaudin_Red[index_jalpha][index_kbeta] = complex<DP> (ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j],
chain.Str_L[k], chain.si_n_anis_over_2));
@ -736,7 +477,8 @@ namespace ABACUS {
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]);
}
@ -753,7 +495,8 @@ namespace ABACUS {
{
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);
@ -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);
return(ReturnState);
}
}
} // namespace ABACUS

ファイルの表示

@ -19,240 +19,201 @@ using namespace ABACUS;
namespace ABACUS {
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
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> 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) {
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)));
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_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));
}
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)) )));
}
// 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)
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);
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.
// 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)
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);
// 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_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;
int 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 == 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;
//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;
// 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) {
SQMat_CX Hm2P(0.0, A.base.Mdown);
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)) *
// (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
complex<DP> sum1 = 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;
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) {
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) {
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) *
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[k] == 1) {
//Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (B.chain.Nsites));
Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (A.chain.Nsites)); // careful !
// use simplified code for one-string here: original form of Hm2P matrix
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
//- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
;
}
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]);
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);
else if (b == B.chain.Str_L[k]) {
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_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);
else {
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);
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 = 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])
* 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]);
sum1 = 0.0;
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) *
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
//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)
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
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)));
// include all string contributions F_B_0 in this term
//Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq);
Hm2P[index_a][index_b] = prod_num * sum1;
Hm2P[index_a][index_b] = prod_num * sum1;
} // else if (b == B.chain.Str_L[k])
} // else
} // else if (b == B.chain.Str_L[k])
} // else
index_b++;
}}} // sums over k, beta, b
index_b++;
}}} // sums over k, beta, b
index_a++;
}}} // sums over j, alpha, a
index_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_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;
complex<DP> ln_overlap = 0.5 * (-ln_prod3 + ln_prod4) + det - 0.5 * (A.lnnorm + B.lnnorm);
//cout << "ln_SZ: " << endl << ln_prod1 << "\t" << -ln_prod2 << "\t" << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
// << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
cout << "ln_overlap: " << endl << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
<< "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
return(ln_form_factor_sq);
*/
complex<DP> ln_overlap = 0.5 * (-ln_prod3 + ln_prod4) + det - 0.5 * (A.lnnorm + B.lnnorm);
return(ln_overlap);
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

ファイルの表示

@ -19,236 +19,222 @@ using namespace ABACUS;
namespace ABACUS {
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
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> 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) {
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)));
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_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);
}
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)) )));
}
// 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)
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);
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.
// 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)
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);
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) {
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;
int index_b = 0;
// Now proceed to build the Hm matrix
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;
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) {
int index_a = 0;
int index_b = 0;
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)) *
(A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
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 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) {
index_b = 0;
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) *
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[k] == 1) {
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);
else if (b == B.chain.Str_L[k]) {
} // if (B.chain.Str_L == 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);
else {
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);
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]) {
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])
* 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]);
sum1 = 0.0;
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) *
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
/*
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)
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
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)));
// include all string contributions F_B_0 in this term
Hm[index_a][index_b] = prod_num * sum1;
Hm[index_a][index_b] = prod_num * sum1;
} // else if (b == B.chain.Str_L[k])
} // else
} // else if (b == B.chain.Str_L[k])
} // else
index_b++;
}}} // sums over k, beta, b
index_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++;
}}} // sums over j, alpha, a
index_a++;
}}} // sums over j, alpha, a
complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
+ 2.0 * real(lndet_LU_CX_dstry(Hm)) - A.lnnorm - B.lnnorm;
complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
+ 2.0 * real(lndet_LU_CX_dstry(Hm)) - A.lnnorm - B.lnnorm;
//return(ln_ME_sq);
return(0.5 * ln_ME_sq); // Return ME, not MEsq
return(0.5 * ln_ME_sq); // Return ME, not MEsq
}
}
} // namespace ABACUS

ファイルの表示

@ -19,325 +19,315 @@ using namespace ABACUS;
namespace ABACUS {
inline complex<DP> ln_Fn_F (XXZ_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0;
int counter = 0;
int arg = 0;
int absarg = 0;
int par_comb_1, par_comb_2;
inline complex<DP> ln_Fn_F (XXZ_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0;
int counter = 0;
int arg = 0;
int absarg = 0;
int par_comb_1, par_comb_2;
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int j = 0; j < B.chain.Nstrings; ++j) {
par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b))) {
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);
/*
prod_temp *= 0.5 * //done later...
((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
* (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
+ B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
*/
prod_temp *= ((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));
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;
}
}}}
if (counter++ > 100) { // we do at most 100 products before taking a log
ans += log(prod_temp);
prod_temp = 1.0;
counter = 0;
}
}}}
return(ans + log(prod_temp));
}
inline complex<DP> ln_Fn_G (XXZ_Bethe_State& A, XXZ_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0;
int counter = 0;
int arg = 0;
int absarg = 0;
int par_comb_1, par_comb_2;
for (int j = 0; j < A.chain.Nstrings; ++j) {
par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
absarg = abs(arg);
/*
prod_temp *= 0.5 * //done later...
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
* (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
- sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j]))
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
+ A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) );
*/
prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
* (A.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
if (counter++ > 100) { // we do at most 100 products before taking a log
ans += log(prod_temp);
prod_temp = 1.0;
counter = 0;
}
}}}
return(ans + log(prod_temp));
}
inline complex<DP> Fn_K (XXZ_Bethe_State& A, int j, int alpha, int a, XXZ_Bethe_State& B, int k, int beta, int b)
{
int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
int absarg1 = abs(arg1);
int arg2 = arg1 + 2;
int absarg2 = abs(arg2);
return(4.0/(
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
* (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
- sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
* (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
+ A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
*
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
* (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
- sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
* (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
+ A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
));
}
inline complex<DP> Fn_L (XXZ_Bethe_State& A, int j, int alpha, int a, XXZ_Bethe_State& B, int k, int beta, int b)
{
return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
+ 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k])))
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
}
complex<DP> ln_Smin_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B)
{
// This function returns the natural log of the S^- operator matrix element.
// The A and B states can contain strings.
// Check that the two states are compatible
if (A.chain != B.chain) 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!");
return(ans + log(prod_temp));
}
// 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();
A.Compute_coshlambda();
B.Compute_sinhlambda();
B.Compute_coshlambda();
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])) )
));
// 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)
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
// Check that the two states are compatible
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)
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);
// 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!");
}
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;
int index_b = 0;
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> 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;
complex<DP> ln_prod1 = 0.0;
complex<DP> ln_prod2 = 0.0;
complex<DP> ln_prod3 = 0.0;
complex<DP> ln_prod4 = 0.0;
for (int i = 0; i < A.chain.Nstrings; ++i)
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
+ 0.25 * II * PI * (1.0 - A.chain.par[i]))));
for (int i = 0; i < B.chain.Nstrings; ++i)
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))));
// Define the F ones earlier...
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
}
}
DP logabssinzeta = log(abs(sin(A.chain.anis)));
// Define regularized products in prefactors
for (int j = 0; j < A.chain.Nstrings; ++j)
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1); // assume only one-strings here
ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
for (int k = 0; k < B.chain.Nstrings; ++k)
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
}
ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
// Now proceed to build the Hm matrix
SQMat_CX Hm(0.0, A.base.Mdown);
int index_a = 0;
int index_b = 0;
complex<DP> sum1 = 0.0;
complex<DP> sum2 = 0.0;
complex<DP> prod_num = 0.0;
complex<DP> Fn_K_0_G_0 = 0.0;
complex<DP> Prod_powerN = 0.0;
complex<DP> Fn_K_1_G_2 = 0.0;
complex<DP> one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
for (int j = 0; j < A.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
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;
index_b = 0;
one_over_A_sinhlambda_sq_plus_sinzetaover2sq = 1.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
* (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
+ pow(sin(0.5*A.chain.anis), 2.0));
one_over_A_sinhlambda_sq_plus_sinzetaover2sq
= 1.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
* (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
+ pow(sin(0.5*A.chain.anis), 2.0));
for (int k = 0; k < B.chain.Nstrings; ++k) {
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
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) {
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) *
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
Prod_powerN = pow( B.chain.par[k] == 1 ?
(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
:
(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
, complex<DP> (B.chain.Nsites));
Prod_powerN = pow( B.chain.par[k] == 1 ?
(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1]
+ II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1]
- II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
:
(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1]
+ II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1]
- II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
, complex<DP> (B.chain.Nsites));
Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
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);
else if (b == 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);
else if (b == B.chain.Str_L[k]) {
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
Vect_CX ln_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);
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
sum1 = 0.0;
sum1 = 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])
* 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]);
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
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]);
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
/*
sum2 = 0.0;
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 = 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
*/
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
Hm[index_a][index_b] = prod_num * sum1;
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
} // else if (b == B.chain.Str_L[k])
} // else
Hm[index_a][index_b] = prod_num * sum1;
index_b++;
}}} // sums over k, beta, b
} // else if (b == B.chain.Str_L[k])
} // else
// now define the elements Hm[a][M]
index_b++;
}}} // sums over k, beta, b
Hm[index_a][B.base.Mdown] = one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
// 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++;
}}} // sums over j, alpha, a
return(0.5 * ln_ME_sq); // Return ME, not MEsq
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

ファイルの表示

@ -19,300 +19,266 @@ using namespace ABACUS;
namespace ABACUS {
inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0;
int counter = 0;
inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0;
int counter = 0;
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
/*
if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(-II * sin(B.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * B.chain.eta * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))));
*/
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b))) {
if (!((j == k) && (alpha == beta) && (a == b))) {
// arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
// absarg = abs(arg);
prod_temp *= -II * (B.sinlambda[j][alpha] * B.coslambda[k][beta] - B.coslambda[j][alpha] * B.sinlambda[k][beta])
* cosh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
(B.coslambda[j][alpha] * B.coslambda[k][beta] + B.sinlambda[j][alpha] * B.sinlambda[k][beta])
* sinh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
prod_temp *= -II * (B.sinlambda[j][alpha] * B.coslambda[k][beta] - B.coslambda[j][alpha] * B.sinlambda[k][beta])
* cosh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
(B.coslambda[j][alpha] * B.coslambda[k][beta] + B.sinlambda[j][alpha] * B.sinlambda[k][beta])
* sinh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
}
}
if (counter++ > 10) { // we do at most 10 products before taking a log
ans += log(prod_temp);
prod_temp = 1.0;
counter = 0;
}
if (counter++ > 10) { // we do at most 10 products before taking a log
ans += log(prod_temp);
prod_temp = 1.0;
counter = 0;
}
}}}
}}}
// return(ans);
return(ans + log(prod_temp));
}
inline complex<DP> ln_Fn_G (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0;
int counter = 0;
for (int j = 0; j < A.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
/*
prod_temp *= -II * sin(A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * B.chain.eta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
*/
// arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
// absarg = abs(arg);
prod_temp *= -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
if (counter++ > 25) { // we do at most 25 products before taking a log
ans += log(prod_temp);
prod_temp = 1.0;
counter = 0;
}
}}}
// return(ans);
return(ans + log(prod_temp));
}
inline complex<DP> Fn_K (XXZ_gpd_Bethe_State& A, int j, int alpha, int a, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
{
/*
return(-1.0/(sin(A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
* sin(A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)))));
*/
// int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
// int absarg1 = abs(arg1);
// int arg2 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b - 1);
// int arg2 = arg1 + 2;
// int absarg2 = abs(arg2);
return(1.0/(( -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))) *
(-II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))) +
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))))));
}
inline complex<DP> Fn_L (XXZ_gpd_Bethe_State& A, int j, int alpha, int a, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
{
/*
complex<DP> ans = -II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))));
return (ans * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
*/
return (-II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))))
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
}
complex<DP> ln_Smin_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B)
{
// This function returns the natural log of the S^- operator matrix element.
// The A and B states can contain strings.
// Check that the two states refer to the same XXZ_gpd_Chain
if (A.chain != B.chain) 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));
}
// return(ans);
return(ans + log(prod_temp));
}
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)
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);
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)));
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)
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);
// 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/(( -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;
int index_b = 0;
ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis)));
complex<DP> sum1 = 0.0;
complex<DP> sum2 = 0.0;
complex<DP> prod_num = 0.0;
complex<DP> Fn_K_0_G_0 = 0.0;
complex<DP> Prod_powerN = 0.0;
complex<DP> Fn_K_1_G_2 = 0.0;
complex<DP> one_over_A_sinlambda_sq_plus_sinhetaover2sq = 0.0;
for (int 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);
}
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_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis)));
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...
+ 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));
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) {
int index_a = 0;
int index_b = 0;
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) *
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);
index_b = 0;
Prod_powerN = pow((B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1]),
complex<DP> (B.chain.Nsites));
one_over_A_sinlambda_sq_plus_sinhetaover2sq =
-1.0/((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))) *
(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);
else if (b == B.chain.Str_L[k]) {
// use simplified code for one-string here: original form of Hm2P matrix
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);
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
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);
Prod_powerN = pow((B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1]
+ II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1]
- II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1]),
complex<DP> (B.chain.Nsites));
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])
* 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]);
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]) {
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) *
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
/*
sum2 = 0.0;
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 jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
*/
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinheta);
sum1 = 0.0;
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
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
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])
} // else
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
index_b++;
}}} // sums over k, beta, b
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]);
// 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++;
}}} // sums over j, alpha, a
Hm[index_a][index_b] = prod_num * sum1;
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;
} // else if (b == B.chain.Str_L[k])
} // else
//return(ln_ME_sq);
return(0.5 * ln_ME_sq); // Return ME, not MEsq
index_b++;
}}} // sums over k, beta, b
}
// now define the elements Hm[a][M]
Hm[index_a][B.base.Mdown] = one_over_A_sinlambda_sq_plus_sinhetaover2sq;
index_a++;
}}} // sums over j, alpha, a
complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
+ 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinheta - A.lnnorm - B.lnnorm;
return(0.5 * ln_ME_sq); // Return ME, not MEsq
}
} // namespace ABACUS

ファイルの表示

@ -18,305 +18,307 @@ using namespace std;
using namespace ABACUS;
namespace ABACUS {
inline complex<DP> phi(complex<DP> x){return x;}
inline complex<DP> a(complex<DP> x){return 1;}
inline complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta){ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
inline complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
inline complex<DP> phi(complex<DP> x){return x;}
inline complex<DP> a(complex<DP> x){return 1;}
inline complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta)
{ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
inline complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N)
{return pow(b(x,xi,eta),N);}
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
}
}
}
return(ans);
}
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
for (int j = 0; j < A.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
}
}
}
return(ans);
}
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]
+ 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)) )));
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)));
}
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)
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++;
}
return(ans);
}
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
{
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
* (A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
}
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
{
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
))
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
}
complex<DP> ln_Smm_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
{
const DP Zero_Center_Thres=1.0e-5;
const DP real_dev=1.0e-14;
const DP Diff_ME_Thres=1.e-6;
// 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);
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 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

ファイルの表示

@ -19,234 +19,230 @@ using namespace ABACUS;
namespace ABACUS {
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
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> 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) {
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)));
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_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));
}
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)) )));
}
// 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)
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);
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.
// 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)
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);
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));
}
}
// 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;
int 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 == 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;
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;
// ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
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) {
// Now proceed to build the Hm2P matrix
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)) *
(A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
int index_a = 0;
int 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) {
complex<DP> sum1 = 0.0;
complex<DP> sum2 = 0.0;
complex<DP> prod_num = 0.0;
complex<DP> Fn_K_0_G_0 = 0.0;
complex<DP> Prod_powerN = 0.0;
complex<DP> Fn_K_1_G_2 = 0.0;
complex<DP> two_over_A_lambda_sq_plus_1over2sq;
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) *
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]);
two_over_A_lambda_sq_plus_1over2sq = 2.0/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
(A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
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
- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
if (B.chain.Str_L[k] == 1) {
}
// 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);
else if (b == B.chain.Str_L[k]) {
Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II),
complex<DP> (B.chain.Nsites));
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);
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
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])
* 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]);
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 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) *
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
sum1 = 0.0;
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)
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
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]);
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])
} // else
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)
sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
index_b++;
}}} // sums over k, beta, b
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
index_a++;
}}} // sums over j, alpha, a
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
//cout << "Matrix: " << endl;
//Hm2P.Print();
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq);
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)
// + 2.0 * real(lndet_LU_CX_dstry(Hm2P))
+ 2.0 * det
- A.lnnorm - B.lnnorm;
index_b++;
}}} // sums over k, beta, b
//cout << "ln_Sz: " << endl << ln_prod1 << "\t" << -ln_prod2 << "\t" << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
// << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
index_a++;
}}} // sums over j, alpha, a
//return(ln_ME_sq);
return(0.5 * ln_ME_sq); // Return ME, not MEsq
DP det = real(lndet_LU_CX_dstry(Hm2P));
}
complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
+ 2.0 * det
- A.lnnorm - B.lnnorm;
return(0.5 * ln_ME_sq); // Return ME, not MEsq
}
} // namespace ABACUS

ファイルの表示

@ -41,21 +41,15 @@ namespace ABACUS {
arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
absarg = abs(arg);
/*
prod_temp *= 0.5 *
((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
* (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
* (sgn_int(arg)
* B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
+ B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
*/
prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
* (B.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
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
@ -90,19 +84,14 @@ namespace ABACUS {
arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
absarg = abs(arg);
/*
prod_temp *= 0.5 *
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
* (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
- sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j]))
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
+ A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) );
*/
prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
* (A.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
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);
@ -213,8 +202,6 @@ namespace ABACUS {
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
ln_Fn_F_B_0 = ln_Fn_F(B, j, alpha, 0);
//re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
//im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F_B_0);
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F_B_0);
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
@ -267,11 +254,12 @@ namespace ABACUS {
index_b = 0;
two_over_A_sinhlambda_sq_plus_sinzetaover2sq = 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
* (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
+ pow(sin(0.5*A.chain.anis), 2.0));
two_over_A_sinhlambda_sq_plus_sinzetaover2sq
= 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
* (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
+ pow(sin(0.5*A.chain.anis), 2.0));
for (int k = 0; k < B.chain.Nstrings; ++k) {
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
@ -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);
Prod_powerN = pow( B.chain.par[k] == 1 ?
(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1]
+ II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1]
- II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
:
(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1]
+ II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1]
- II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
, complex<DP> (B.chain.Nsites));
//cout << "Prod_powerN = " << Prod_powerN << "\t" << abs(Prod_powerN) << endl;
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq
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);
}
@ -314,7 +305,8 @@ namespace ABACUS {
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])
* 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;
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)
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));
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
}
@ -405,14 +395,14 @@ namespace ABACUS {
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
ln_prod1 += log(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
+ 0.25 * II * PI * (1.0 - A.chain.par[i])));
+ 0.25 * II * PI * (1.0 - A.chain.par[i])));
complex<DP> shB;
for (int i = 0; i < B.chain.Nstrings; ++i)
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
if (norm(shB = sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
//ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
// + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
ln_prod2 += log(shB);

ファイルの表示

@ -19,301 +19,265 @@ using namespace ABACUS;
namespace ABACUS {
inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0;
int counter = 0;
inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
complex<DP> prod_temp = 1.0;
int counter = 0;
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
/*
if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(-II * sin(B.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * B.chain.eta * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))));
*/
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b))) {
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 (!((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])
* 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));
}
return(ans + log(prod_temp));
}
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)
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);
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)));
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)
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);
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/(( -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;
int index_b = 0;
ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis)));
complex<DP> sum1 = 0.0;
complex<DP> sum2 = 0.0;
complex<DP> prod_num = 0.0;
complex<DP> Fn_K_0_G_0 = 0.0;
complex<DP> Prod_powerN = 0.0;
complex<DP> Fn_K_1_G_2 = 0.0;
complex<DP> two_over_A_sinlambda_sq_plus_sinhetaover2sq = 0.0;
for (int 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);
}
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_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis)));
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...
+ 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));
SQMat_CX Hm2P(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) {
int index_a = 0;
int index_b = 0;
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) *
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);
index_b = 0;
Prod_powerN = pow((B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1]),
complex<DP> (B.chain.Nsites));
two_over_A_sinlambda_sq_plus_sinhetaover2sq
= -2.0/((sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
+ 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a))) *
(sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
+ 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)))
+ pow(sinh(0.5*A.chain.anis), 2.0));
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
- two_over_A_sinlambda_sq_plus_sinhetaover2sq * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinheta);
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) {
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);
else if (b == B.chain.Str_L[k]) {
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
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);
Prod_powerN = pow((B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1]
+ II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1])
/(B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1]
- II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1]),
complex<DP> (B.chain.Nsites));
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);
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
- two_over_A_sinlambda_sq_plus_sinhetaover2sq * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinheta);
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])
* 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]);
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]) {
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) *
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 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);
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)
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
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
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])
} // else
sum2 = 0.0;
index_b++;
}}} // sums over k, beta, b
index_a++;
}}} // sums over j, alpha, a
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)
sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
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;
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1]
- 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"
// << lndet_LU_CX(Hm2P) << endl;
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
//return(ln_ME_sq);
return(0.5 * ln_ME_sq); // Return ME, not MEsq
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinlambda_sq_plus_sinhetaover2sq);
}
} // else if (b == B.chain.Str_L[k])
} // else
index_b++;
}}} // sums over k, beta, b
index_a++;
}}} // sums over j, alpha, a
complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
+ 2.0 * real(lndet_LU_CX_dstry(Hm2P)) - A.lnnorm - B.lnnorm;
return(0.5 * ln_ME_sq); // Return ME, not MEsq
}
} // namespace ABACUS

ファイルの表示

@ -20,499 +20,355 @@ using namespace ABACUS;
namespace ABACUS {
inline complex<DP> phi(complex<DP> x){return x;}
inline complex<DP> a(complex<DP> x){return 1;}
inline complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta){ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
inline complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
inline complex<DP> phi(complex<DP> x){return x;}
inline complex<DP> a(complex<DP> x){return 1;}
inline complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta){ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
inline complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
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> 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) {
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)));
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)
{
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));
}
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
{
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
))
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
}
complex<DP> ln_Szm_p_Smz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
{
//clock_t start_time_local = clock();
//A has to be the ground state!
complex<DP> ln_Szm_p_Smz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
{
//clock_t start_time_local = clock();
//A has to be the ground state!
// This function returns the natural log of the S^z operator matrix element.
// The A and B states can contain strings.
// 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
// 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
for (int i = 0; i < A.chain.Nstrings; ++i)
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
if(abs(A.lambda[i][alpha])<5.55112e-12)A.lambda[i][alpha]=5.55112e-12;
for (int i = 0; i < B.chain.Nstrings; ++i)
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
if(abs(B.lambda[i][alpha])<5.55112e-5)B.lambda[i][alpha]=5.55112e-5;
//add a delta to the origin of the centered strings
for (int i = 0; i < A.chain.Nstrings; ++i)
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
if(abs(A.lambda[i][alpha])<5.55112e-12)A.lambda[i][alpha]=5.55112e-12;
for (int i = 0; i < B.chain.Nstrings; ++i)
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
if(abs(B.lambda[i][alpha])<5.55112e-5)B.lambda[i][alpha]=5.55112e-5;
// Some convenient arrays
// Some convenient arrays
complex<DP> i=complex<DP>(0.0,1.0);
complex<DP> eta=-i;
complex<DP> ln_prod = complex<DP>(0.0,0.0);
complex<DP> result;
result=log(B.chain.Nsites*1.0/4.0);
complex<DP> i=complex<DP>(0.0,1.0);
complex<DP> eta=-i;
complex<DP> ln_prod = complex<DP>(0.0,0.0);
complex<DP> result;
result=log(B.chain.Nsites*1.0/4.0);
int sizeA=0;
int sizeB=0;
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];
for (int i = 0; i < A.chain.Nstrings; ++i)
sizeA+=A.base.Nrap[i]*A.chain.Str_L[i];
for (int i = 0; i < B.chain.Nstrings; ++i)
sizeB+=B.base.Nrap[i]*B.chain.Str_L[i];
complex<DP>* mu = new complex<DP>[sizeA];
complex<DP>* lam = new complex<DP>[sizeB];
int index=0;
for (int i = 0; i < A.chain.Nstrings; ++i)
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
{
// mu[index]=(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
mu[index]=(A.lambda[i][alpha] + 0.5 * -eta * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
index++;
}
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 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
lam[index]=(B.lambda[i][alpha] + 0.5 * -eta * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
index++;
}
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);
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;
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 < 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)));
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...
// Define the F ones earlier...
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
for (int 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));
}
}
}
//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)
// 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)))
// now define the elements Hm[a][M]
// for (int i = 0; i < B.chain.Nstrings; ++i)
// for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
// for (int a = 1; a <= B.chain.Str_L[i]; ++a)
// ln_prod+=-log(abs(phi(-(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a))+eta*0.5)));
// for (int i = 0; i < B.chain.Nstrings; ++i)
// for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
// for (int a = 1; a <= B.chain.Str_L[i]; ++a)
// for (int j = 0; j < B.chain.Nstrings; ++j)
// for (int beta = 0; beta < B.base.Nrap[j]; ++beta)
// for (int b = 1; b <= B.chain.Str_L[j]; ++b)
// if(i!=j || alpha!=beta ||a!=b)ln_prod3+=-0.5*log(abs(phi((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a))-(B.lambda[j][beta] + 0.5 * II * (B.chain.Str_L[j] + 1.0 - 2.0 * b))-eta)));
// for (int i = 0; i < A.chain.Nstrings; ++i)
// for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
// for (int a = 1; a <= A.chain.Str_L[i]; ++a)
// for (int j = 0; j < A.chain.Nstrings; ++j)
// for (int beta = 0; beta < A.base.Nrap[j]; ++beta)
// for (int b = 1; b <= A.chain.Str_L[j]; ++b)
// if(abs((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a))-(A.lambda[j][beta] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * b))-eta)!=0 && (i!=j && alpha!=beta && a!=b))
// ln_prod3+=-0.5*log(abs((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a))-(A.lambda[j][beta] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * b))-eta));
//mu is the ground state!
//A -> mu, B -> lam
complex<DP> prod=complex<DP>(1.0,0.0);
complex<DP> prod2=complex<DP>(1.0,0.0);
complex<DP> prod3=complex<DP>(1.0,0.0);
for(int l=0; l<sizeA;l++) prod*=phi(mu[l]+eta*0.5);
for(int l=0; l<sizeB;l++) prod/=phi(lam[l]+eta*0.5);
for(int l=0; l<sizeA;l++)
for(int m=0; m<sizeA;m++)
if(l!=m)prod2*=1.0/sqrt(abs(phi(mu[m]-mu[l]-eta)));
for(int l=0; l<sizeB;l++)
for(int m=0; m<sizeB;m++)
if(abs(lam[m]-lam[l]-eta)!=0 && l!=m)prod3*=1.0/sqrt(abs(phi(lam[m]-lam[l]-eta)));
result+=2.0*log(abs(prod))-2.0*log(prod3)+2.0*log(prod2) - A.lnnorm - B.lnnorm;// a factor prod3^2 is inserted in the determinant!
// cout<<"prod:"<<prod<<endl;
SQMat_CX Hm(0.0, A.base.Mdown);
//complex<DP> H[sizeA][sizeA];
// cout<<"mu[l]:";
// for(int l=0; l<sizeA;l++)
// cout<<mu[l]<<", ";
// cout<<endl;
// cout<<"lam[l]:";
// for(int l=0; l<sizeB;l++)
// cout<<lam[l]<<", ";
// cout<<endl;
int index_a = 0;
int index_b = 0;
complex<DP> Prod_powerN;
for (int j = 0; j < A.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
index_b = 0;
for (int k = 0; k < B.chain.Nstrings; ++k) {
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
if (B.chain.Str_L[k] == 1) {
complex<DP> prodplus= complex<DP>(1.0,0.0);
complex<DP> prodminus= complex<DP>(1.0,0.0);
// use simplified code for one-string here: original form of Hm2P matrix
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
Prod_powerN = pow((B.lambda[k][beta] -eta*0.5) /(B.lambda[k][beta] +eta*0.5), complex<DP> (B.chain.Nsites));
Hm[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
} // if (B.chain.Str_L == 1)
else {
if (b > 1) Hm[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)*exp(ln_Fn_G(A,B,k,beta,b-1))*exp(-real(ln_Fn_F(B, k, beta, b - 1)));//.../ prod_l!=k | phi(lam[l]-lam[k]) |
else if (b == 1) {
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
complex<DP> sum1 = complex<DP>(0.0,0.0);
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1] //sum term when i=0
- ln_FunctionF[0] - ln_FunctionF[1]);
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) //sum term when i=n
* exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
Hm[index_a][index_b] = eta * exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum1 * exp( - real(ln_Fn_F(B, k, beta, b - 1))); //the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
} // else if (b == B.chain.Str_L[k])
} // else
index_b++;
}}} // sums over k, beta, b
// now define the elements Hm[a][M]
//Hm[index_a][B.base.Mdown] = one_over_A_lambda_sq_plus_1over2sq;
//Hm[index_a][B.base.Mdown] = eta/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
// (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
Hm[index_a][B.base.Mdown] = eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
index_a++;
}}} // sums over j, alpha, a
// cout<<"Hm:";
// for(int j=0; j<sizeA;j++){
// for(int k=0; k<sizeA;k++) cout<<"Hm["<<j<<"]["<<k<<"]:"<<Hm[j][k]<<", ";
// cout<<endl;
// }
complex<DP> F= complex<DP>(0.0,0.0);
complex<DP> detmatrix;
detmatrix=exp(lndet_LU_CX_dstry(Hm));
//cout<<"exp(lndet_LU_CX(Hm)):"<<abs(detmatrix)<<endl;
// cout<<"exp(i*(A.K-B.K))+1.0):"<<exp(i*(A.K-B.K))+1.0<<"det(matrix):"<<detmatrix<<endl;
//F=-(exp(-i*(A.K-B.K))+1.0)*detmatrix;
//mu is the ground state!
//A -> mu, B -> lam
SQMat_CX G(0.0, A.base.Mdown);
SQMat_CX BbDa(0.0, A.base.Mdown);
index_a = 0;
for (int j = 0; j < A.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
index_b = 0;
complex<DP> Da;
complex<DP> Ca;
Da=eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
Ca=eta*((mu[index_a]-eta*0.5)+(mu[index_a]+eta*0.5))/pow(((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5)),2.0);
for (int k = 0; k < B.chain.Nstrings; ++k) {
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
/*if (B.chain.Str_L[k] == 1) {
complex<DP> Bb;
Bb=-(phi(lam[index_b]+eta*0.5)+phi(lam[index_b]-eta*0.5));
complex<DP> product=complex<DP>(1.0,0.0);
for(int o=0; o<sizeB;o++)product*=phi(lam[o]-lam[index_b]+eta);
Bb*=product;
complex<DP> prodplus= complex<DP>(1.0,0.0);
complex<DP> prodminus= complex<DP>(1.0,0.0);
// use simplified code for one-string here: original form of Hm2P matrix
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
//prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta]);// - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
// prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta]);// - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
Prod_powerN = pow((B.lambda[k][beta] - eta*0.5) /(B.lambda[k][beta] + eta*0.5), complex<DP> (B.chain.Nsites));
G[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
BbDa[index_a][index_b]=Bb*Da*exp(- re_ln_Fn_F_B_0[k][beta]);
} // if (B.chain.Str_L == 1)
else {
*/{
if (b > 1){
G[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)*exp(ln_Fn_G(A,B,k,beta,b-1))*exp(-real(ln_Fn_F(B, k, beta, b - 1)));//.../ prod_l!=k | phi(lam[l]-lam[k]) |
BbDa[index_a][index_b] =0 ;
}
else if (b == 1) {
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
complex<DP> sum1 = complex<DP>(0.0,0.0);
complex<DP> sum2 = complex<DP>(0.0,0.0);
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1]
- ln_FunctionF[0] - ln_FunctionF[1]);//sum term when i=0
//sum2 doesn't have a i=0 term
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
* exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); //sum term when i=n
sum2 += exp(ln_FunctionG[B.chain.Str_L[k]]- ln_FunctionF[B.chain.Str_L[k]] )
* (phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * B.chain.Str_L[k]))-eta*0.5)
+ phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * B.chain.Str_L[k]))+eta*0.5) ); //sum term when i=n
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) {
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
sum2 += exp(ln_FunctionG[jsum]- ln_FunctionF[jsum] )
* (phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * jsum))-eta*0.5)
+ phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * jsum))+eta*0.5) );
}
G[index_a][index_b] = eta * exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum1 * exp( - real(ln_Fn_F(B, k, beta, b - 1))); //the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
BbDa[index_a][index_b] = - Da* exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum2 * exp( - real(ln_Fn_F(B, k, beta, b - 1)));//the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
} // else if (b == B.chain.Str_L[k])
} // else
index_b++;
}}} // sums over k, beta, b
// now define the elements Hm[a][M]
//Hm[index_a][B.base.Mdown] = eta/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) * (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
G[index_a][B.base.Mdown]=Ca;
BbDa[index_a][B.base.Mdown]=0;
index_a++;
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
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> F= complex<DP>(0.0,0.0);
// cout<<"matrix:";
// for(int j=0; j<sizeA;j++){
// for(int k=0; k<sizeA;k++) cout<<"matrix["<<j<<"]["<<k<<"]:"<<matrix[j][k]<<", ";
// cout<<endl;
// }
// cout<<"matrixtest:";
// for(int j=0; j<sizeA;j++){
// for(int k=0; k<sizeA;k++) cout<<"matrixtest["<<j<<"]["<<k<<"]:"<<matrixtest[j][k]<<", ";
// cout<<endl;
// }
complex<DP> detmatrix;
detmatrix=exp(lndet_LU_CX_dstry(Hm));
// cout<<"BbDa[a][b]:";
// for(int j=0; j<sizeA;j++){
// for(int k=0; k<sizeA;k++) cout<<"BbDa["<<j<<"]["<<k<<"]:"<<BbDa[j][k]<<", ";
// cout<<endl;
// }
// cout<<"Bn[b]*Da[a]:";
// for(int j=0; j<sizeA;j++){
// for(int k=0; k<sizeA;k++) cout<<"test["<<j<<"]["<<k<<"]:"<<Bn[k]*Da[j]<<", ";
// cout<<endl;
// }
//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;
// cout<<"prod:"<<prod<<endl;
// cout<<"(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G))):"<<(exp(lndet_LU_CX(matrix))-exp(lndet_LU_CX(G)))<<endl;
// cout<<"(exp(lndet_LU_CX_dstry(matrix)):"<<(exp(lndet_LU_CX(matrix)))<<endl;
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) {
//cout<<" an(n):"<<an(n)<<" det(matrix):"<<det(matrix)<< " det(Gn):"<<det(Gn)<<" an(n)*(det(matrix)-det(Gn)):"<<an(n)*(det(matrix)-det(Gn))<<endl;
complex<DP> sum=prod*(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G)));
//sum=conj(prod)*(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G)));
index_b = 0;
//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;
// cout<<"F1:"<<F*sqrt(exp(result))<<" F2:"<<F2*sqrt(exp(result))<<" F3:"<<F3*sqrt(exp(result))<<endl;
// cout<<"abs(F1)^2:"<<abs(F*F*(exp(result)))<<" abs(F2)^2:"<<abs(F2*F2*(exp(result)))<<" abs(F3)^2:"<<abs(F3*F3*(exp(result)))<<endl;
// cout<<"arg(F1):"<<-i*log(F*sqrt(exp(result))/abs(F*sqrt(exp(result))))/M_PI<<" arg(F2):"<<-i*log(F2*sqrt(exp(result))/abs(F2*sqrt(exp(result))))/M_PI<<" arg(F3):"<<-i*log(F3*sqrt(exp(result))/abs(F3*sqrt(exp(result))))/M_PI<<endl;
// cout<<"F:"<<(F)<<endl;
// cout<<"Smff:"<<exp(result)*4.0*abs(detmatrix*detmatrix)<<endl;
{
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]
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);
// cout<<"sum:"<<sum<<endl;
// cout<<"exp(result):"<<exp(result)<<endl;
//TEST!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
result+=2.0*log(abs(F));
result-=log(A.chain.Nsites-A.base.Mdown*2+2.0);
//result*=pow(abs((exp(i*(A.K-B.K))+1.0)*detmatrix),2);//*(exp(i*(A.K-B.K))+1.0)
//result*=pow(abs(2.0*exp(i*(A.K-B.K))*sum),2);
//result/=(B.chain.Nsites)*1/16.0;
//cout<<"TEST::::::::::::::::::::::"<<"A.Check_Admissibility('a'):"<<A.Check_Admissibility('a')<<endl;
//cout<<"mu:"<<mu<<" lam:"<<lam<<endl;
// cout<<"an(n):"<<an<<endl;
// cout<<"prod^2:"<<pow(abs(prod),2)<<endl;
// cout<<"prod3:"<<prod3<<endl;
// cout<<"prod2:"<<prod2<<endl;
complex<DP> ln_ME_sq = result;
delete[] mu;
delete[] lam;
// cout<<"normlam"<<"normmu:"<<(exp(A.lnnorm))<<":"<<(exp(B.lnnorm))<<endl;
// cout<<"abs(prod*prod*prod2*sum_n):"<<abs(prod*prod*prod2*sum_n)<<endl;
return(0.5 * ln_ME_sq); // Return ME, not MEsq
//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

ファイルの表示

@ -19,62 +19,62 @@ using namespace ABACUS;
namespace ABACUS {
complex<DP> phi(complex<DP> x){return x;}
complex<DP> a(complex<DP> x){return 1;}
complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta){ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
complex<DP> phi(complex<DP> x){return x;}
complex<DP> a(complex<DP> x){return 1;}
complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta){ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
{
complex<DP> ans = 0.0;
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
if (!((j == k) && (alpha == beta) && (a == b)))
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
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> 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) {
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)));
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)
{
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));
}
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
{
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
))
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
}
complex<DP> ln_Szz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B){
//clock_t start_time_local = clock();
@ -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 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.
// 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
// 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> ln_prod = complex<DP>(0.0,0.0);
complex<DP> result=-300;
complex<DP> prev_result=-300;
complex<DP> eta=-II;
complex<DP> ln_prod = complex<DP>(0.0,0.0);
complex<DP> result=-300;
complex<DP> prev_result=-300;
//if(A.String_delta()> HEIS_deltaprec) return(complex<DP>(-300.0)); // DEPRECATED in ++T_9
if((A.E)==(B.E) && B.chain.Nsites ==B.base.Mdown*2){
return(2*log(abs((B.E+(B.chain.Nsites)/4.0)/(3.0*sqrt(B.chain.Nsites)))));
}
XXX_Bethe_State A_origin; A_origin=A;
bool zero_string=false;
for (int j = 0; j < A_origin.chain.Nstrings; ++j)
for (int alpha = 0; alpha < A_origin.base.Nrap[j]; ++alpha)
if(abs(A_origin.lambda[j][alpha])<Zero_Center_Thres) zero_string=true;
// Some convenient arrays
bool real_dev_conv=false;
int dev=-1;
while(!real_dev_conv){
real_dev_conv=true;
dev++;
//add a delta to the origin of the centered strings
if(zero_string){
real_dev_conv=false;
for (int j = 0; j < A.chain.Nstrings; ++j)
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
if(abs(A_origin.lambda[j][alpha])<Zero_Center_Thres)
A.lambda[j][alpha]=real_dev*pow(10.0,dev);
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;
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++;
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*/
//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);
}
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);
prev_result=result;
//add manualy the ground state value
int sizeA=0;
int sizeB=0;
for (int i = 0; i < A.chain.Nstrings; ++i)
sizeA+=A.base.Nrap[i]*A.chain.Str_L[i];
for (int i = 0; i < B.chain.Nstrings; ++i)
sizeB+=B.base.Nrap[i]*B.chain.Str_L[i];
complex<DP>* mu = new complex<DP>[sizeA];
complex<DP>* lam = new complex<DP>[sizeB];
int index=0;
for (int i = 0; i < A.chain.Nstrings; ++i)
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
{
mu[index]=(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
index++;
}
index=0;
for (int i = 0; i < B.chain.Nstrings; ++i)
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
{
lam[index]=(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
index++;
}
Lambda re_ln_Fn_F_A_0(A.chain, A.base);
Lambda im_ln_Fn_F_A_0(A.chain, A.base);
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
Lambda re_ln_Fn_G_0(B.chain, B.base);
Lambda im_ln_Fn_G_0(B.chain, B.base);
Lambda re_ln_Fn_G_2(B.chain, B.base);
Lambda im_ln_Fn_G_2(B.chain, B.base);
complex<DP> ln_prod1 = 0.0;
complex<DP> ln_prod2 = 0.0;
complex<DP> ln_prod3 = 0.0;
complex<DP> ln_prod4 = 0.0;
for (int i = 0; i < A.chain.Nstrings; ++i)
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
ln_prod1 += log(norm(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
for (int i = 0; i < B.chain.Nstrings; ++i)
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
if (norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)) > 100.0 * MACHINE_EPS_SQ)
ln_prod2 += log(norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
// Define the F ones earlier...
for (int j = 0; j < A.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
re_ln_Fn_F_A_0[j][alpha] = real(ln_Fn_F(A, j, alpha, 0));
im_ln_Fn_F_A_0[j][alpha] = imag(ln_Fn_F(A, j, alpha, 0));
}
}
for (int j = 0; j < B.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
}
}
// Define regularized products in prefactors
for (int k = 0; k < A.chain.Nstrings; ++k)
for (int beta = 0; beta < A.base.Nrap[k]; ++beta)
for (int b = 1; b <= A.chain.Str_L[k]; ++b) {
if (b == 1)ln_prod3 += re_ln_Fn_F_A_0[k][beta];
else if (b > 1) ln_prod3 += ln_Fn_F(A, k, beta, b - 1);/*TEST*/
}
for (int k = 0; k < B.chain.Nstrings; ++k)
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
}
complex<DP> prod=complex<DP>(1.0,0.0);
for(int l=0; l<sizeA;l++) prod*=phi(mu[l]+eta*0.5);
for(int l=0; l<sizeB;l++) prod/=phi(lam[l]+eta*0.5);
double factor = log((B.chain.Nsites)*1/16.0);
factor +=(2.0*log(abs(prod)) - real(ln_prod3) + real(ln_prod4) - A.lnnorm - B.lnnorm);
// a factor prod4^-2 is inserted in the determinant!
int index_a = 0;
int index_b = 0;
complex<DP> Prod_powerN;
SQMat_CX H(0.0, A.base.Mdown);
SQMat_CX P(0.0, A.base.Mdown);
index_a = 0;
for (int j = 0; j < A.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
index_b = 0;
complex<DP> Da;
complex<DP> Ca;
Da=eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
for (int k = 0; k < B.chain.Nstrings; ++k) {
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
if (B.chain.Str_L[k] == 1) {
complex<DP> Bb=complex<DP>(1.0,0.0);
for(int o=0; o<sizeB;o++)Bb*=phi(lam[o]-lam[index_b]+eta);
complex<DP> prodplus= complex<DP>(1.0,0.0);
complex<DP> prodminus= complex<DP>(1.0,0.0);
// use simplified code for one-string here: original form of Hm2P matrix
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
Prod_powerN = pow((B.lambda[k][beta] - eta*0.5) /(B.lambda[k][beta] + eta*0.5),
complex<DP> (B.chain.Nsites));
H[index_a][index_b] = eta*(prodplus-prodminus*Prod_powerN);
P[index_a][index_b] = Bb*Da*exp(- re_ln_Fn_F_B_0[k][beta]);
} // if (B.chain.Str_L == 1)
else {
if (b > 1){
H[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)
*exp(ln_Fn_G(A,B,k,beta,b-1))*exp(-real(ln_Fn_F(B, k, beta, b - 1)));
//.../ prod_l!=k | phi(lam[l]-lam[k]) |
P[index_a][index_b] =0 ;
}
else if (b == 1) {
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
complex<DP> sum1 = complex<DP>(0.0,0.0);
complex<DP> sum2 = complex<DP>(0.0,0.0);
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1]
- ln_FunctionF[0] - ln_FunctionF[1]);//sum term when i=0
//sum2 doesn't have a i=0 term
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
* exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); //sum term when i=n
sum2 += exp(ln_FunctionG[B.chain.Str_L[k]]- ln_FunctionF[B.chain.Str_L[k]] ); //sum term when i=n
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) {
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
sum2 += exp(ln_FunctionG[jsum]- ln_FunctionF[jsum] );
}
H[index_a][index_b] = eta * exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1])
* sum1 * exp( - real(ln_Fn_F(B, k, beta, b - 1)));
//the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
P[index_a][index_b] = - Da* exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1])
* sum2 * exp( - real(ln_Fn_F(B, k, beta, b - 1)));
//the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
} // else if (b == B.chain.Str_L[k])
} // else
index_b++;
}}} // sums over k, beta, b
index_a++;
}}} // sums over j, alpha, a
complex<DP> F= complex<DP>(0.0,0.0);
SQMat_CX matrix(0.0, A.base.Mdown);
for(int j=0; j<sizeA;j++)
for(int k=0; k<sizeA;k++){
matrix[j][k]=(H[j][k]-2.0*P[j][k]);
}
complex<DP> detmatrix;
detmatrix=exp(lndet_LU_CX_dstry(matrix)+0.5*factor);
SQMat_CX Gn(0.0, A.base.Mdown);
complex<DP> sum_n=complex<DP>(0.0,0.0);
for(int n=0; n<sizeA;n++){
complex<DP> An;
An=-phi(lam[n]-eta*0.5);
for(int m=0; m<sizeA;m++)
An*=phi(lam[m]-lam[n]+eta);
SQMat_CX Gn(0.0, A.base.Mdown);
SQMat_CX BnbDa(0.0, A.base.Mdown);
index_a = 0;
for (int j = 0; j < A.chain.Nstrings; ++j) {
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
index_b = 0;
complex<DP> Da;
complex<DP> Ca;
Da=eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
Ca=(eta)*((mu[index_a]-eta*0.5)+(mu[index_a]+eta*0.5))/pow(((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5)),2.0);
for (int k = 0; k < B.chain.Nstrings; ++k) {
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
if(index_b==n){
Gn[index_a][index_b] = Ca*exp(-real(ln_Fn_F(B, k, beta, b - 1)));
BnbDa[index_a][index_b] = 0;
} // else (index_b!=n)
else if (B.chain.Str_L[k] == 1) {
complex<DP> Bnb;
Bnb=-phi(lam[index_b]+eta*0.5)/phi(lam[n]-lam[index_b]-eta);
complex<DP> product=complex<DP>(1.0,0.0);
for(int o=0; o<sizeB;o++)product*=phi(lam[o]-lam[index_b]+eta);
Bnb*=product;
complex<DP> prodplus= complex<DP>(1.0,0.0);
complex<DP> prodminus= complex<DP>(1.0,0.0);
// use simplified code for one-string here: original form of Hm2P matrix
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta]
- re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta]
- re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
Prod_powerN = pow((B.lambda[k][beta] - eta*0.5) /(B.lambda[k][beta] + eta*0.5),
complex<DP> (B.chain.Nsites));
Gn[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
BnbDa[index_a][index_b]=Bnb*Da*exp(- re_ln_Fn_F_B_0[k][beta]);
} // if (B.chain.Str_L == 1)
else{
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;
}
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]);
//return(result);
return(0.5 * result); // Return ME, not MEsq
}
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

ファイルの表示

@ -30,8 +30,6 @@ namespace ABACUS {
rhomin = rhomin_ref;
rhomax = rhomax_ref;
prec = req_prec;
//rho_tbl = Vect_DP (Nvals + 1);
//I_tbl = Vect_DP (Nvals + 1);
rho_tbl = new DP[Nvals + 1];
I_tbl = new DP[Nvals + 1];
@ -40,7 +38,6 @@ namespace ABACUS {
for (int i = 0; i <= Nvals ; ++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);
}
@ -51,14 +48,11 @@ namespace ABACUS {
DP I_table::Return_val (DP req_rho) {
//cout << "requesting I of " << req_rho << endl;
DP used_rho = fabs(req_rho);
if (used_rho < rhomin || used_rho >= rhomax)
{
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));
}
@ -67,7 +61,8 @@ namespace ABACUS {
// 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 () {
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();
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) {
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();
const char* infilename = infile_str.c_str();
@ -105,8 +102,6 @@ namespace ABACUS {
rhomin = rhomin_ref;
rhomax = rhomax_ref;
prec = req_prec;
//rho_tbl = Vect_DP (Nvals + 1);
//I_tbl = Vect_DP (Nvals + 1);
rho_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) {
//cout << "requesting I of " << req_rho << endl;
if (req_rho < rhomin || req_rho >= rhomax)
{
cerr << "Requesting I of " << setprecision(16) << req_rho << " with rho_min = " << rhomin << endl;
@ -192,10 +185,12 @@ namespace ABACUS {
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;
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();
const char* infilename = infile_str.c_str();
@ -203,7 +198,6 @@ namespace ABACUS {
infile.open(infilename);
if (infile.fail()) {
//cout << "Failed to load file " << infilename << endl;
return (false);
}
@ -238,8 +232,6 @@ namespace ABACUS {
{
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 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));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
DP dx = (xmax - xmin)/Npts;
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)
{
//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) {
//cout << "Warning: integral didn't converge between " << setprecision(10) << xmin << " and " << xmax << endl;
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];
@ -313,31 +297,33 @@ namespace ABACUS {
DP I1 = dx * (f1[0] + f1[1] + f1[2]);
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 = dx * (f1[3] + f1[4] + f1[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 = dx * (f1[6] + f1[7] + f1[8]);
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;
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));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
DP* f = new DP[3];
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;
//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);
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 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) {
//cout << "Warning: integral didn't converge between " << setprecision(10) << xmin << " and " << xmax << endl;
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];
@ -397,19 +375,22 @@ namespace ABACUS {
DP I1 = dx * (f1[0] + f1[1] + f1[2]);
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 = dx * (f1[3] + f1[4] + f1[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 = dx * (f1[6] + f1[7] + f1[8]);
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;
@ -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 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));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
if (xmax < xmin) return(-Integrate_rec_using_table (function, args, arg_to_integ, Itable, xmax, xmin,
req_prec, max_rec_level));
DP* f = new DP[3];
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;
//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;
@ -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 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) {
//cout << "Warning: integral didn't converge between " << setprecision(10) << xmin << " and " << xmax << endl;
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];
@ -464,49 +437,46 @@ namespace ABACUS {
args[arg_to_integ] = xmin + 0.5 * dx;
f1[0] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[0] << endl;
outfile << args << "\t" << f1[0] << endl;
f1[1] = f[0];
args[arg_to_integ] = xmin + 2.5 * dx;
f1[2] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[2] << endl;
outfile << args << "\t" << f1[2] << endl;
args[arg_to_integ] = xmin + 3.5 * dx;
f1[3] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[3] << endl;
outfile << args << "\t" << f1[3] << endl;
f1[4] = f[1];
args[arg_to_integ] = xmin + 5.5 * dx;
f1[5] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[5] << endl;
outfile << args << "\t" << f1[5] << endl;
args[arg_to_integ] = xmin + 6.5 * dx;
f1[6] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[6] << endl;
outfile << args << "\t" << f1[6] << endl;
f1[7] = f[2];
args[arg_to_integ] = xmin + 8.5 * dx;
f1[8] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f1[8] << endl;
outfile << args << "\t" << f1[8] << endl;
DP I1_pre = 3.0 * dx * f[0];
DP I1 = dx * (f1[0] + f1[1] + f1[2]);
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 = dx * (f1[3] + f1[4] + f1[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 = dx * (f1[6] + f1[7] + f1[8]);
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;
@ -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 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));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
if (xmax < xmin) return(-Integrate_rec_using_table (function, args, arg_to_integ, Itable, xmax, xmin,
req_prec, max_rec_level, outfile));
DP* f = new DP[3];
DP dx = (xmax - xmin)/3.0;
@ -528,34 +497,28 @@ namespace ABACUS {
for (int i = 0; i < 3; ++i) {
args[arg_to_integ] = xmin + (i + 0.5) * dx;
f[i] = function (args, Itable);
//outfile << args[arg_to_integ] << "\t" << f[i] << endl;
outfile << args << "\t" << f[i] << endl;
sum_fabs_f += fabs(f[i]);
}
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;
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 xmin, DP xmax, DP req_prec, int rec_level, int max_rec_level, DP* f, ofstream& outfile)
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 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) {
//cout << "Warning: integral didn't converge between " << setprecision(10) << xmin << " and " << xmax << endl;
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];
@ -563,61 +526,58 @@ namespace ABACUS {
args[arg_to_integ] = xmin + 0.5 * dx;
f1[0] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[0] << endl;
outfile << args << "\t" << f1[0] << endl;
f1[1] = f[0];
args[arg_to_integ] = xmin + 2.5 * dx;
f1[2] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[2] << endl;
outfile << args << "\t" << f1[2] << endl;
args[arg_to_integ] = xmin + 3.5 * dx;
f1[3] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[3] << endl;
outfile << args << "\t" << f1[3] << endl;
f1[4] = f[1];
args[arg_to_integ] = xmin + 5.5 * dx;
f1[5] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[5] << endl;
outfile << args << "\t" << f1[5] << endl;
args[arg_to_integ] = xmin + 6.5 * dx;
f1[6] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[6] << endl;
outfile << args << "\t" << f1[6] << endl;
f1[7] = f[2];
args[arg_to_integ] = xmin + 8.5 * dx;
f1[8] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f1[8] << endl;
outfile << args << "\t" << f1[8] << endl;
DP I1_pre = 3.0 * dx * f[0];
DP I1 = dx * (f1[0] + f1[1] + f1[2]);
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 = dx * (f1[3] + f1[4] + f1[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 = dx * (f1[6] + f1[7] + f1[8]);
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;
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 xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile)
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 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));
//cout << "Calling Integrate on argument " << arg_to_integ << " between " << xmin << " and " << xmax << " to prec " << req_prec << endl;
if (xmax < xmin)
return(-Integrate_rec_using_table_and_file (function, args, arg_to_integ, Itable, xmax, xmin,
req_prec, max_rec_level, outfile));
DP* f = new DP[3];
DP dx = (xmax - xmin)/3.0;
@ -627,16 +587,14 @@ namespace ABACUS {
for (int i = 0; i < 3; ++i) {
args[arg_to_integ] = xmin + (i + 0.5) * dx;
f[i] = function (args, Itable, outfile);
//outfile << args[arg_to_integ] << "\t" << f[i] << endl;
outfile << args << "\t" << f[i] << endl;
sum_fabs_f += fabs(f[i]);
}
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;
@ -645,20 +603,14 @@ namespace ABACUS {
// 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 xmin, DP xmax, DP eta_old, DP req_prec, int rec_level, int max_rec_level, DP* f, ofstream& outfile)
DP Integrate_exp_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ,
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);
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])));
}
//if (rec_level > 16) ABACUSerror("Recursion level too high in Integrate_rec.");
DP* f1 = 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]);
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 = 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)
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 = 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)
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;
@ -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 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.
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 < 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;
if (xmax < xmin) return(-Integrate_exp_using_table (function, args, arg_to_integ, Itable, xmax, xmin,
req_prec, max_rec_level, outfile));
DP* f = new DP[3];
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;
@ -747,9 +700,8 @@ namespace ABACUS {
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;
@ -761,11 +713,11 @@ namespace ABACUS {
// *********************************** Adaptive Riemann sum (better implementation) *******************************************
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()
{
@ -803,12 +755,10 @@ namespace ABACUS {
}
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;
xmax = xmax_ref;
@ -838,12 +788,10 @@ namespace ABACUS {
}
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;
xmax = xmax_ref;
@ -873,9 +821,6 @@ namespace ABACUS {
}
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)
@ -960,9 +905,12 @@ namespace ABACUS {
args[arg_to_integ] = new_data[index_new + 8].x;
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 + 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_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]);
@ -995,7 +943,8 @@ namespace ABACUS {
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
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;
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_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]);
@ -1101,7 +1053,8 @@ namespace ABACUS {
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
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;
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_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]);
@ -1207,35 +1163,31 @@ namespace ABACUS {
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.");
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);
}
// REMOVE next four line
//ofstream outfile;
//outfile.open("testoptimal.dat");
//outfile.precision(16);
//integ_dat.Save(outfile);
return(integ_dat.integ_res);
}
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.");
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);
}
@ -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_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.");
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);
}
@ -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,
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.");
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);
@ -1280,11 +1236,12 @@ namespace ABACUS {
// *********************************** Adaptive Riemann sum (better implementation) *******************************************
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()
{
@ -1292,7 +1249,8 @@ namespace ABACUS {
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;
xmax = xmax_ref;
@ -1322,48 +1280,9 @@ namespace ABACUS {
}
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...
/*
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)
{
// Reset file writing position
@ -1482,114 +1401,6 @@ namespace ABACUS {
}
// 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,
DP req_rel_prec, DP req_abs_prec, int max_nr_pts)
{
@ -1605,43 +1416,5 @@ namespace ABACUS {
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

ファイルの表示

@ -19,7 +19,8 @@ using namespace std;
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.
@ -41,7 +42,8 @@ namespace ABACUS {
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
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,
I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile)
Integral_result Integrate_optimal_par_using_table (MPI_Comm comm, DP (*function) (Vect_DP, I_table),
Vect_DP& args, int arg_to_integ,
I_table Itable, DP xmin, DP xmax,
DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile)
{
if (xmax < xmin) 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) {
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);