Clean up sources up to (before) src/SCAN.
This commit is contained in:
parent
d337885305
commit
e7dd24d337
19
ABACUS.org
19
ABACUS.org
|
@ -1,5 +1,5 @@
|
|||
#+TODO: TODO(t@) | DONE(d@)
|
||||
#+TODO: BUGREPORT(b@) CRITICAL(#@) | SOLVED(s@)
|
||||
#+TODO: BUGREPORT(b@) BUGRISK(?@) CRITICAL(#@) | SOLVED(s@)
|
||||
#+TODO: CONCEPT(c@) UPDATED(u@) | REJECTED(r@)
|
||||
#+TODO: PICKEDUP(p@) | ABANDONED(k@) IMPLEMENTED(i@)
|
||||
|
||||
|
@ -24,6 +24,23 @@ Type your description here
|
|||
:END:
|
||||
|
||||
|
||||
* Bugrisks :ABACUS:Dev:Bugrisks:
|
||||
:PROPERTIES:
|
||||
:ARCHIVE: %s_archive::* Bugrisks
|
||||
:CUSTOM_ID: Bugrisks
|
||||
:END:
|
||||
|
||||
TIP: Search for the string BUGRISK in the codebase
|
||||
|
||||
** BUGRISK Value of LiebLin ln_Density_ME
|
||||
- State "BUGRISK" from "" [2018-02-11 Sun 09:11]
|
||||
|
||||
File: ln_Density_ME.cc
|
||||
line 66
|
||||
|
||||
Why real?
|
||||
|
||||
|
||||
* Priority :ABACUS:Dev:Priority:
|
||||
:PROPERTIES:
|
||||
:ARCHIVE: %s_archive::* Priority
|
||||
|
|
|
@ -25,11 +25,16 @@ $ make
|
|||
```
|
||||
This will produce all executables, together with a library `ABACUS_[vn]` where vn is of the form [digit][character].
|
||||
|
||||
## Warnings
|
||||
* The ODSLF part (for one-dimensional spinless fermions) is not functional: it is based on the old Young Tableaux ids, and must be upgraded to `State_Label`s.
|
||||
* The Richardson part is not implemented; what exists is old and long deprecated.
|
||||
|
||||
## Acknowledgements
|
||||
__Antoine Klauser__ provided functions for computing neighbour-operator-product matrix elements in XXX: `ln_Szz_ME`, `ln_Szm_p_Smz_ME` and `ln_Smm_ME`.
|
||||
|
||||
__Jacopo De Nardis__ provided the code for the `ln_g2_ME` function for Lieb-Liniger.
|
||||
__Miłosz Panfil__ contributed to code to help in the calculation of finite-temperature correlations of Lieb-Liniger.
|
||||
|
||||
__Jacopo De Nardis__ contributed code for the `ln_g2_ME` function for Lieb-Liniger.
|
||||
|
||||
__Teun Zwart__ has given much useful advice concerning C++ code organization.
|
||||
|
||||
|
|
|
@ -24,27 +24,26 @@ namespace ABACUS {
|
|||
|
||||
LiebLin_Bethe_State::LiebLin_Bethe_State ()
|
||||
: c_int (0.0), L(0.0), cxL(0.0), N(0),
|
||||
//OriginStateIxe(Vect<int>(0,1)),
|
||||
Ix2_available(Vect<int>(0, 1)), index_first_hole_to_right (Vect<int>(0,1)), displacement (Vect<int>(0,1)),
|
||||
Ix2(Vect<int>(0, 1)), lambdaoc(Vect<DP>(0.0, 1)), //BE(Vect<DP>(0.0, 1)),
|
||||
Ix2(Vect<int>(0, 1)), lambdaoc(Vect<DP>(0.0, 1)),
|
||||
S(Vect<DP>(0.0, 1)), dSdlambdaoc(Vect<DP>(0.0, 1)),
|
||||
diffsq(0.0), prec(ITER_REQ_PREC_LIEBLIN), conv(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0)
|
||||
{
|
||||
stringstream Nout; Nout << N; label = Nout.str() + LABELSEP + ABACUScoding[0] + LABELSEP;//"_0_";
|
||||
stringstream Nout; Nout << N; label = Nout.str() + LABELSEP + ABACUScoding[0] + LABELSEP;
|
||||
}
|
||||
|
||||
LiebLin_Bethe_State::LiebLin_Bethe_State (DP c_int_ref, DP L_ref, int N_ref)
|
||||
: c_int(c_int_ref), L(L_ref), cxL(c_int_ref * L_ref), N(N_ref),
|
||||
//OriginStateIx2(Vect<int>(0,N),
|
||||
Ix2_available(Vect<int>(0, 2)), index_first_hole_to_right (Vect<int>(0,N)), displacement (Vect<int>(0,N)),
|
||||
Ix2(Vect<int>(0, N)), lambdaoc(Vect<DP>(0.0, N)), //BE(Vect<DP>(0.0, N)),
|
||||
Ix2(Vect<int>(0, N)), lambdaoc(Vect<DP>(0.0, N)),
|
||||
S(Vect<DP>(0.0, N)), dSdlambdaoc(Vect<DP>(0.0, N)),
|
||||
diffsq(0.0), prec(ABACUS::max(1.0, 1.0/(c_int * c_int)) * ITER_REQ_PREC_LIEBLIN), conv(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0)
|
||||
diffsq(0.0), prec(ABACUS::max(1.0, 1.0/(c_int * c_int)) * ITER_REQ_PREC_LIEBLIN),
|
||||
conv(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0)
|
||||
{
|
||||
if (c_int < 0.0) ABACUSerror("You must use a positive interaction parameter !");
|
||||
if (N < 0) ABACUSerror("Particle number must be strictly positive.");
|
||||
|
||||
stringstream Nout; Nout << N; label = Nout.str() + LABELSEP + ABACUScoding[0] + LABELSEP;//+ "_0_";
|
||||
stringstream Nout; Nout << N; label = Nout.str() + LABELSEP + ABACUScoding[0] + LABELSEP;
|
||||
|
||||
// Set quantum numbers to ground-state configuration:
|
||||
for (int i = 0; i < N; ++i) Ix2[i] = -(N-1) + 2*i;
|
||||
|
@ -52,7 +51,6 @@ namespace ABACUS {
|
|||
Vect<int> OriginIx2 = Ix2;
|
||||
|
||||
(*this).Set_Label_from_Ix2 (OriginIx2);
|
||||
//(*this).Set_Label_Internals_from_Ix2 (OriginIx2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -69,7 +67,6 @@ namespace ABACUS {
|
|||
displacement = RefState.displacement;
|
||||
Ix2 = RefState.Ix2;
|
||||
lambdaoc = RefState.lambdaoc;
|
||||
//BE = RefState.BE;
|
||||
S = RefState.S;
|
||||
dSdlambdaoc = RefState.dSdlambdaoc;
|
||||
diffsq = RefState.diffsq;
|
||||
|
@ -114,11 +111,7 @@ namespace ABACUS {
|
|||
// Now reorder the Ix2 to follow convention:
|
||||
Ix2.QuickSort();
|
||||
|
||||
//cout << "Setting label:" << label_ref << endl << "Ix2old = " << labeldata.Ix2old[0] << endl << "Ix2exc = " << labeldata.Ix2exc[0] << endl;
|
||||
//cout << "on " << OriginStateIx2ordered << endl << "giving " << Ix2 << endl;
|
||||
|
||||
(*this).Set_Label_from_Ix2 (OriginStateIx2ordered);
|
||||
//(*this).Set_Label_Internals_from_Ix2 (OriginStateIx2ordered);
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Set_to_Label (string label_ref)
|
||||
|
@ -138,7 +131,6 @@ namespace ABACUS {
|
|||
|
||||
if (N != OriginStateIx2.size()) ABACUSerror("N != OriginStateIx2.size() in Set_Label_from_Ix2.");
|
||||
|
||||
//cout << "Setting label on Ix2 " << endl << Ix2 << endl;
|
||||
|
||||
// Set the state label:
|
||||
Vect<int> type_ref(0,1);
|
||||
|
@ -173,44 +165,8 @@ namespace ABACUS {
|
|||
label = Return_State_Label (labeldata, OriginStateIx2);
|
||||
}
|
||||
|
||||
/*
|
||||
void LiebLin_Bethe_State::Set_Label_from_Ix2 (const Vect<int>& OriginStateIx2)
|
||||
{
|
||||
// This function was deprecated since it assumed that the Ix2 of the state were
|
||||
// in a particular order mirroring the indices of OriginStateIx2.
|
||||
|
||||
if (N != OriginStateIx2.size()) ABACUSerror("N != OriginStateIx2.size() in Set_Label_from_Ix2.");
|
||||
|
||||
Vect<int> OriginStateIx2ordered = OriginStateIx2;
|
||||
OriginStateIx2ordered.QuickSort();
|
||||
|
||||
// Set the state label:
|
||||
Vect<int> type_ref(0,1);
|
||||
Vect<int> M_ref(N, 1);
|
||||
Vect<int> nexc_ref(0, 1);
|
||||
// Count nr of particle-holes:
|
||||
for (int i = 0; i < N; ++i) if (Ix2[i] != OriginStateIx2ordered[i]) nexc_ref[0] += 1;
|
||||
Vect<Vect<int> > Ix2old_ref(1);
|
||||
Vect<Vect<int> > Ix2exc_ref(1);
|
||||
Ix2old_ref[0] = Vect<int>(ABACUS::max(nexc_ref[0],1));
|
||||
Ix2exc_ref[0] = Vect<int>(ABACUS::max(nexc_ref[0],1));
|
||||
int nexccheck = 0;
|
||||
for (int i = 0; i < N; ++i)
|
||||
if (Ix2[i] != OriginStateIx2ordered[i]) {
|
||||
Ix2old_ref[0][nexccheck] = OriginStateIx2ordered[i];
|
||||
Ix2exc_ref[0][nexccheck++] = Ix2[i];
|
||||
}
|
||||
|
||||
State_Label_Data labeldata(type_ref, M_ref, nexc_ref, Ix2old_ref, Ix2exc_ref);
|
||||
|
||||
label = Return_State_Label (labeldata);
|
||||
}
|
||||
*/
|
||||
|
||||
void LiebLin_Bethe_State::Set_Label_Internals_from_Ix2 (const Vect<int>& OriginStateIx2)
|
||||
{
|
||||
//ABACUSerror("LiebLin_Bethe_State::Set_Label_Internals_from_Ix2 deprecated 20110604");
|
||||
|
||||
if (N != OriginStateIx2.size()) ABACUSerror("N != OriginStateIx2.size() in Set_Label_Internals_from_Ix2.");
|
||||
|
||||
Vect<int> OriginStateIx2ordered = OriginStateIx2;
|
||||
|
@ -238,12 +194,14 @@ namespace ABACUS {
|
|||
label = Return_State_Label (labeldata, OriginStateIx2);
|
||||
|
||||
// Construct the Ix2_available vector: we give one more quantum number on left and right:
|
||||
int navailable = 2 + (ABACUS::max(Ix2.max(), OriginStateIx2.max()) - ABACUS::min(Ix2.min(), OriginStateIx2.min()))/2 - N + 1;
|
||||
int navailable = 2 + (ABACUS::max(Ix2.max(), OriginStateIx2.max())
|
||||
- ABACUS::min(Ix2.min(), OriginStateIx2.min()))/2 - N + 1;
|
||||
Ix2_available = Vect<int>(navailable);
|
||||
index_first_hole_to_right = Vect<int>(N);
|
||||
|
||||
// First set Ix2_available to all holes from left
|
||||
for (int i = 0; i < Ix2_available.size(); ++i) Ix2_available[i] = ABACUS::min(Ix2.min(), OriginStateIx2.min()) - 2 + 2*i;
|
||||
for (int i = 0; i < Ix2_available.size(); ++i)
|
||||
Ix2_available[i] = ABACUS::min(Ix2.min(), OriginStateIx2.min()) - 2 + 2*i;
|
||||
|
||||
// Now shift according to Ix2 of OriginState:
|
||||
for (int j = 0; j < N; ++j) {
|
||||
|
@ -261,11 +219,10 @@ namespace ABACUS {
|
|||
for (int j = 0; j < N; ++j) {
|
||||
if (Ix2[j] < OriginStateIx2ordered[j]) {
|
||||
// Ix2[j] must be equal to some OriginState_Ix2_available[i] for i < OriginState_index_first_hole_to_right[j]
|
||||
//cout << "Going down\t" << Ix2[j] << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << endl;
|
||||
while (Ix2[j] != Ix2_available[index_first_hole_to_right[j] + displacement[j] ]) {
|
||||
//cout << j << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << "\t" << Ix2_available[index_first_hole_to_right[j] + displacement[j] ] << endl;
|
||||
if (index_first_hole_to_right[j] + displacement[j] == 0) {
|
||||
cout << label << endl << j << endl << OriginStateIx2 << endl << Ix2 << endl << Ix2_available << endl << index_first_hole_to_right << endl << displacement << endl;
|
||||
cout << label << endl << j << endl << OriginStateIx2 << endl << Ix2 << endl << Ix2_available
|
||||
<< endl << index_first_hole_to_right << endl << displacement << endl;
|
||||
ABACUSerror("Going down too far in Set_Label_Internals...");
|
||||
}
|
||||
displacement[j]--;
|
||||
|
@ -273,23 +230,17 @@ namespace ABACUS {
|
|||
}
|
||||
if (Ix2[j] > OriginStateIx2ordered[j]) {
|
||||
// Ix2[j] must be equal to some Ix2_available[i] for i >= index_first_hole_to_right[j]
|
||||
//cout << "Going up\t" << Ix2[j] << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << endl;
|
||||
displacement[j] = 1; // start with this value to prevent segfault
|
||||
while (Ix2[j] != Ix2_available[index_first_hole_to_right[j] - 1 + displacement[j] ]) {
|
||||
//cout << j << "\t" << index_first_hole_to_right[j] << "\t" << displacement[j] << "\t" << Ix2_available[index_first_hole_to_right[j] + displacement[j] ] << endl;
|
||||
if (index_first_hole_to_right[j] + displacement[j] == Ix2_available.size() - 1) {
|
||||
cout << label << endl << j << endl << OriginStateIx2 << endl << Ix2 << endl << Ix2_available << endl << index_first_hole_to_right << endl << displacement << endl;
|
||||
cout << label << endl << j << endl << OriginStateIx2 << endl << Ix2 << endl << Ix2_available
|
||||
<< endl << index_first_hole_to_right << endl << displacement << endl;
|
||||
ABACUSerror("Going up too far in Set_Label_Internals...");
|
||||
}
|
||||
displacement[j]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
//cout << "label " << label << endl;
|
||||
//cout << "Ix2: " << Ix2 << endl << "Ix2_available: " << Ix2_available << endl << "index...: " << index_first_hole_to_right << endl << "displacement: " << displacement << endl;
|
||||
//char a; cin >> a;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool LiebLin_Bethe_State::Check_Admissibility (char whichDSF)
|
||||
|
@ -307,43 +258,25 @@ namespace ABACUS {
|
|||
diffsq = 1.0;
|
||||
|
||||
if (reset_rapidities) (*this).Set_Free_lambdaocs();
|
||||
/*
|
||||
// Start with normal iterations:
|
||||
//for (int niternormal = 0; niternormal < 10; ++niternormal) {
|
||||
for (int niternormal = 0; niternormal < N; ++niternormal) {
|
||||
//(*this).Iterate_BAE(0.99);
|
||||
(*this).Iterate_BAE(0.9);
|
||||
cout << "Normal: " << niternormal << "\t" << diffsq << endl;
|
||||
cout << (*this).lambdaoc << endl;
|
||||
if (diffsq < sqrt(prec)) break;
|
||||
}
|
||||
*/
|
||||
|
||||
iter_Newton = 0;
|
||||
|
||||
DP damping = 1.0;
|
||||
DP diffsq_prev = 1.0e+6;
|
||||
//while (diffsq > prec && !is_nan(diffsq) && iter_Newton < 40) {
|
||||
while (diffsq > prec && !is_nan(diffsq) && iter_Newton < 100) {
|
||||
//while (diffsq > prec && !is_nan(diffsq) && iter_Newton < 400) {
|
||||
(*this).Iterate_BAE_Newton(damping);
|
||||
//(*this).Iterate_BAE_S(damping); // Not as fast as Newton for N up to ~ 256
|
||||
//if (diffsq > diffsq_prev) damping /= 2.0;
|
||||
if (diffsq > diffsq_prev && damping > 0.5) damping /= 2.0;
|
||||
else if (diffsq < diffsq_prev) damping = 1.0;
|
||||
diffsq_prev = diffsq;
|
||||
//cout << iter_Newton << "\t" << diffsq << "\t" << damping << endl;
|
||||
//cout << (*this).lambdaoc << endl;
|
||||
}
|
||||
|
||||
conv = ((diffsq < prec) && (*this).Check_Rapidities()) ? 1 : 0;
|
||||
|
||||
if (!conv) {
|
||||
cout << "Alert! State " << label << " did not converge... diffsq " << diffsq << "\titer_Newton " << iter_Newton << (*this) << endl;
|
||||
//char a; cin >> a;
|
||||
cout << "Alert! State " << label << " did not converge... diffsq " << diffsq
|
||||
<< "\titer_Newton " << iter_Newton << (*this) << endl;
|
||||
}
|
||||
|
||||
//cout << (*this) << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -388,7 +321,8 @@ namespace ABACUS {
|
|||
|
||||
// Add the pieces outside of Gaudin determinant
|
||||
|
||||
for (int j = 0; j < N - 1; ++j) for (int k = j+1; k < N; ++k) lnnorm += log(1.0 + 1.0/pow(lambdaoc[j] - lambdaoc[k], 2.0));
|
||||
for (int j = 0; j < N - 1; ++j) for (int k = j+1; k < N; ++k)
|
||||
lnnorm += log(1.0 + 1.0/pow(lambdaoc[j] - lambdaoc[k], 2.0));
|
||||
|
||||
}
|
||||
|
||||
|
@ -413,15 +347,10 @@ namespace ABACUS {
|
|||
|
||||
// For small values of c, use better approximation using approximate zeroes of Hermite polynomials: see Gaudin eqn 4.71.
|
||||
if (cxL < 1.0) {
|
||||
//DP sqrtcL = pow(cxL, 0.5);
|
||||
DP oneoversqrtcLN = 1.0/pow(cxL * N, 0.5);
|
||||
for (int a = 0; a < N; ++a) lambdaoc[a] = oneoversqrtcLN * PI * Ix2[a];
|
||||
|
||||
//for (int a = 0; a < N; ++a) lambdaoc[a] = sqrtcL * PI * Ix2[a]; // wrong values, correct scaling with c
|
||||
//for (int a = 0; a < N; ++a) lambdaoc[a] = PI * Ix2[a]/(cxL + 2.0 * N); // set to minimal distance lattice
|
||||
}
|
||||
|
||||
//cout << "Set free lambdaocs to: " << endl << lambdaoc << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -443,19 +372,13 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
diffsq = 0.0;
|
||||
//DP sumsq = 0.0;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
lambdaoc[i] += dlambdaoc[i];
|
||||
//sumsq += lambdaoc[i] * lambdaoc[i];
|
||||
//diffsq += dlambdaoc[i] * dlambdaoc[i];
|
||||
//if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i];
|
||||
//else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i];
|
||||
// Normalize the diffsq by the typical value of the rapidities:
|
||||
if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
|
||||
else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
|
||||
}
|
||||
diffsq /= DP(N);
|
||||
//diffsq /= sqrt(sumsq) * DP(N);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -463,7 +386,8 @@ namespace ABACUS {
|
|||
void LiebLin_Bethe_State::Iterate_BAE_S (DP damping)
|
||||
{
|
||||
// This is essentially Newton's method but only in one variable.
|
||||
// The logic is that the derivative of the LHS of the BE_j w/r to lambdaoc_j is much larger than with respect to lambdaoc_l with l != j.
|
||||
// The logic is that the derivative of the LHS of the BE_j w/r to lambdaoc_j is much larger
|
||||
// than with respect to lambdaoc_l with l != j.
|
||||
|
||||
Vect_DP dlambdaoc (0.0, N);
|
||||
|
||||
|
@ -475,7 +399,8 @@ namespace ABACUS {
|
|||
S[j] *= 2.0/cxL;
|
||||
|
||||
dSdlambdaoc[j] = 0.0;
|
||||
for (int k = 0; k < N; ++k) dSdlambdaoc[j] += 1.0/((lambdaoc[j] - lambdaoc[k]) * (lambdaoc[j] - lambdaoc[k]) + 1.0);
|
||||
for (int k = 0; k < N; ++k)
|
||||
dSdlambdaoc[j] += 1.0/((lambdaoc[j] - lambdaoc[k]) * (lambdaoc[j] - lambdaoc[k]) + 1.0);
|
||||
dSdlambdaoc[j] *= 2.0/(PI * cxL);
|
||||
|
||||
dlambdaoc[j] = (PI*Ix2[j]/cxL - S[j] + lambdaoc[j] * dSdlambdaoc[j])/(1.0 + dSdlambdaoc[j]) - lambdaoc[j];
|
||||
|
@ -526,8 +451,6 @@ namespace ABACUS {
|
|||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
//cout << j << "\t" << Ix2[j] << "\t" << atanintshift << endl;
|
||||
|
||||
RHSBAE[j] = cxL * lambdaoc[j] + sumtheta - PI*(Ix2[j] - atanintshift);
|
||||
}
|
||||
|
||||
|
@ -535,14 +458,10 @@ namespace ABACUS {
|
|||
|
||||
for (int j = 0; j < N; ++j) dlambdaoc[j] = - RHSBAE[j];
|
||||
|
||||
//cout << "dlambdaoc pre lubksb = " << dlambdaoc << endl;
|
||||
|
||||
DP d;
|
||||
ludcmp (Gaudin, indx, d);
|
||||
lubksb (Gaudin, indx, dlambdaoc);
|
||||
|
||||
//cout << "dlambdaoc post lubksb = " << dlambdaoc << endl;
|
||||
|
||||
bool ordering_changed = false;
|
||||
for (int j = 0; j < N-1; ++j) if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) ordering_changed = true;
|
||||
|
||||
|
@ -553,71 +472,35 @@ namespace ABACUS {
|
|||
DP maxdlambdaoc = 0.0;
|
||||
do {
|
||||
ordering_still_changed = false;
|
||||
if (dlambdaoc[0] < 0.0 && fabs(dlambdaoc[0]) > (maxdlambdaoc = 10.0*ABACUS::max(fabs(lambdaoc[0]), fabs(lambdaoc[N-1]))))
|
||||
if (dlambdaoc[0] < 0.0 && fabs(dlambdaoc[0])
|
||||
> (maxdlambdaoc = 10.0*ABACUS::max(fabs(lambdaoc[0]), fabs(lambdaoc[N-1]))))
|
||||
dlambdaoc[0] = -maxdlambdaoc;
|
||||
if (lambdaoc[0] + dlambdaoc[0] > lambdaoc[1] + dlambdaoc[1]) {
|
||||
dlambdaoc[0] = 0.25 * (lambdaoc[1] + dlambdaoc[1] - lambdaoc[0] ); // max quarter distance
|
||||
ordering_still_changed = true;
|
||||
//cout << "reason 1" << endl;
|
||||
}
|
||||
if (dlambdaoc[N-1] > 0.0 && fabs(dlambdaoc[N-1]) > (maxdlambdaoc = 10.0*ABACUS::max(fabs(lambdaoc[0]), fabs(lambdaoc[N-1]))))
|
||||
if (dlambdaoc[N-1] > 0.0 && fabs(dlambdaoc[N-1])
|
||||
> (maxdlambdaoc = 10.0*ABACUS::max(fabs(lambdaoc[0]), fabs(lambdaoc[N-1]))))
|
||||
dlambdaoc[N-1] = maxdlambdaoc;
|
||||
if (lambdaoc[N-1] + dlambdaoc[N-1] < lambdaoc[N-2] + dlambdaoc[N-2]) {
|
||||
dlambdaoc[N-1] = 0.25 * (lambdaoc[N-2] + dlambdaoc[N-2] - lambdaoc[N-1]);
|
||||
ordering_still_changed = true;
|
||||
//cout << "reason 2" << endl;
|
||||
}
|
||||
for (int j = 1; j < N-1; ++j) {
|
||||
if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) {
|
||||
dlambdaoc[j] = 0.25 * (lambdaoc[j+1] + dlambdaoc[j+1] - lambdaoc[j]);
|
||||
ordering_still_changed = true;
|
||||
//cout << "reason 3" << endl;
|
||||
}
|
||||
if (lambdaoc[j] + dlambdaoc[j] < lambdaoc[j-1] + dlambdaoc[j-1]) {
|
||||
dlambdaoc[j] = 0.25 * (lambdaoc[j-1] + dlambdaoc[j-1] - lambdaoc[j]);
|
||||
ordering_still_changed = true;
|
||||
//cout << "reason 4" << endl;
|
||||
}
|
||||
}
|
||||
} while (ordering_still_changed);
|
||||
}
|
||||
|
||||
//if (ordering_changed) cout << "dlambdaoc post checking = " << dlambdaoc << endl;
|
||||
|
||||
/*
|
||||
bool orderingchanged = false;
|
||||
//bool dlambdaexceedsmaxrapdiff = false;
|
||||
DP damping_to_use = damping;
|
||||
for (int j = 0; j < N-1; ++j) {
|
||||
if (lambdaoc[j] + dlambdaoc[j] > lambdaoc[j+1] + dlambdaoc[j+1]) // unacceptable, order changed!
|
||||
orderingchanged = true;
|
||||
// We must damp the dlambda such that the ordering is unchanged:
|
||||
// the condition is lambdaoc[j] + damping*dlambdaoc[j] < lambdaoc[j+1] + damping*dlambdaoc[j+1]
|
||||
damping_to_use = ABACUS::min(damping_to_use, 0.5 * (lambdaoc[j+1] - lambdaoc[j])/(dlambdaoc[j] - dlambdaoc[j+1]));
|
||||
}
|
||||
*/
|
||||
//for (int j = 0; j < N; ++j)
|
||||
//if (fabs(dlambdaoc[j]) > maxrapdiff) dlambdaexceedsmaxrapdiff = true;
|
||||
/*
|
||||
// The dlambdaoc must be smaller than the distance to neighbouring rapidities:
|
||||
// If any dlambdaoc is greater than half the distance, set all to half the previous distance:
|
||||
if (orderingchanged || dlambdaexceedsmaxrapdiff) {
|
||||
if (dlambdaoc[0] > 0.0) dlambdaoc[0] = 0.25 * (lambdaoc[1] - lambdaoc[0]);
|
||||
//else dlambdaoc[0] = 0.25 * (lambdaoc[0] - lambdaoc[1]);
|
||||
else dlambdaoc[0] = -fabs(lambdaoc[0]); // strictly limit the growth of lambdaoc[0]
|
||||
//if (dlambdaoc[N-1] > 0.0) dlambdaoc[N-1] = 0.25 * (lambdaoc[N-1] - lambdaoc[N-2]);
|
||||
if (dlambdaoc[N-1] > 0.0) dlambdaoc[N-1] = fabs(lambdaoc[N-1]); // strictly limit the growth of lambdaoc[N-1]
|
||||
else dlambdaoc[N-1] = 0.25 * (lambdaoc[N-2] - lambdaoc[N-1]);
|
||||
for (int j = 1; j < N-1; ++j) {
|
||||
if (dlambdaoc[j] > 0.0) dlambdaoc[j] = 0.25 * (lambdaoc[j+1] - lambdaoc[j]);
|
||||
if (dlambdaoc[j] < 0.0) dlambdaoc[j] = 0.25 * (lambdaoc[j-1] - lambdaoc[j]);
|
||||
}
|
||||
//cout << "Corrected dlambdaoc = " << dlambdaoc << endl;
|
||||
}
|
||||
*/
|
||||
diffsq = 0.0;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
//diffsq += dlambdaoc[i] * dlambdaoc[i];
|
||||
// Normalize the diffsq by the typical value of the rapidities:
|
||||
if (cxL > 1.0) diffsq += dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
|
||||
else diffsq += cxL * cxL * dlambdaoc[i] * dlambdaoc[i]/(lambdaoc[i] * lambdaoc[i] + 1.0e-6);
|
||||
|
@ -627,20 +510,20 @@ namespace ABACUS {
|
|||
if (ordering_changed) diffsq = 1.0; // reset if Newton wanted to change ordering
|
||||
|
||||
for (int j = 0; j < N; ++j) lambdaoc[j] += damping * dlambdaoc[j];
|
||||
//for (int j = 0; j < N; ++j) lambdaoc[j] += damping_to_use * dlambdaoc[j];
|
||||
|
||||
iter_Newton++;
|
||||
|
||||
// if we've converged, calculate the norm here, since the work has been done...
|
||||
|
||||
//if (diffsq < prec && !orderingchanged && !dlambdaexceedsmaxrapdiff) {
|
||||
if (diffsq < prec && !ordering_changed) {
|
||||
|
||||
lnnorm = 0.0;
|
||||
for (int j = 0; j < N; j++) lnnorm += log(fabs(Gaudin[j][j]));
|
||||
|
||||
// Add the pieces outside of Gaudin determinant
|
||||
for (int j = 0; j < N - 1; ++j) for (int k = j+1; k < N; ++k) lnnorm += log(1.0 + 1.0/pow(lambdaoc[j] - lambdaoc[k], 2.0));
|
||||
for (int j = 0; j < N - 1; ++j)
|
||||
for (int k = j+1; k < N; ++k)
|
||||
lnnorm += log(1.0 + 1.0/pow(lambdaoc[j] - lambdaoc[k], 2.0));
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -657,7 +540,6 @@ namespace ABACUS {
|
|||
{
|
||||
iK = 0;
|
||||
for (int j = 0; j < N; ++j) {
|
||||
//cout << j << "\t" << iK << "\t" << Ix2[j] << endl;
|
||||
iK += Ix2[j];
|
||||
}
|
||||
if (iK % 2) {
|
||||
|
@ -683,7 +565,8 @@ namespace ABACUS {
|
|||
void LiebLin_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<DP>& Gaudin_Red)
|
||||
{
|
||||
|
||||
if (Gaudin_Red.size() != N) ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
if (Gaudin_Red.size() != N)
|
||||
ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
|
||||
DP sum_Kernel = 0.0;
|
||||
|
||||
|
@ -717,7 +600,8 @@ namespace ABACUS {
|
|||
|
||||
if (!ck) ABACUSerror("Choose a parity invariant state please");
|
||||
|
||||
if (Gaudin_Red.size() != N/2) ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
if (Gaudin_Red.size() != N/2)
|
||||
ABACUSerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
|
||||
DP sum_Kernel = 0.0;
|
||||
|
||||
|
@ -726,11 +610,14 @@ namespace ABACUS {
|
|||
|
||||
if (j == k) {
|
||||
sum_Kernel = 0.0;
|
||||
for (int kp = N/2; kp < N; ++kp) if (j + N/2 != kp) sum_Kernel += Kernel (lambdaoc[j+N/2] - lambdaoc[kp]) + Kernel (lambdaoc[j+N/2] + lambdaoc[kp]);
|
||||
for (int kp = N/2; kp < N; ++kp)
|
||||
if (j + N/2 != kp)
|
||||
sum_Kernel += Kernel (lambdaoc[j+N/2] - lambdaoc[kp]) + Kernel (lambdaoc[j+N/2] + lambdaoc[kp]);
|
||||
Gaudin_Red[j][k] = cxL + sum_Kernel;
|
||||
}
|
||||
|
||||
else Gaudin_Red[j][k] = - (Kernel (lambdaoc[j+ N/2] - lambdaoc[k+ N/2]) + Kernel (lambdaoc[j+ N/2] + lambdaoc[k+ N/2]) );
|
||||
else Gaudin_Red[j][k] = - (Kernel (lambdaoc[j+ N/2] - lambdaoc[k+ N/2])
|
||||
+ Kernel (lambdaoc[j+ N/2] + lambdaoc[k+ N/2]) );
|
||||
|
||||
}
|
||||
|
||||
|
@ -743,14 +630,12 @@ namespace ABACUS {
|
|||
// This function changes the Ix2 of a given state by annihilating a particle and hole
|
||||
// pair specified by ipart and ihole (counting from the left, starting with index 0).
|
||||
|
||||
//cout << "Annihilating ipart " << ipart << " and ihole " << ihole << " of state with label " << (*this).label << endl;
|
||||
|
||||
State_Label_Data currentdata = Read_State_Label ((*this).label, OriginStateIx2);
|
||||
//cout << "current Ix2old " << currentdata.Ix2old[0] << endl;
|
||||
//cout << "current Ix2exc " << currentdata.Ix2exc[0] << endl;
|
||||
|
||||
if (ipart >= currentdata.nexc[0]) ABACUSerror("Particle label too large in LiebLin_Bethe_State::Annihilate_ph_pair.");
|
||||
if (ihole >= currentdata.nexc[0]) ABACUSerror("Hole label too large in LiebLin_Bethe_State::Annihilate_ph_pair.");
|
||||
if (ipart >= currentdata.nexc[0])
|
||||
ABACUSerror("Particle label too large in LiebLin_Bethe_State::Annihilate_ph_pair.");
|
||||
if (ihole >= currentdata.nexc[0])
|
||||
ABACUSerror("Hole label too large in LiebLin_Bethe_State::Annihilate_ph_pair.");
|
||||
|
||||
// Simply remove the given pair:
|
||||
Vect<int> type_new = currentdata.type;
|
||||
|
@ -770,14 +655,10 @@ namespace ABACUS {
|
|||
Ix2exc_new[it][i] = currentdata.Ix2exc[it][i + (i >= ipart)];
|
||||
}
|
||||
}
|
||||
//cout << "Ix2old_new " << Ix2old_new[0] << endl;
|
||||
//cout << "Ix2exc_new " << Ix2exc_new[0] << endl;
|
||||
|
||||
State_Label_Data newdata (type_new, M_new, nexc_new, Ix2old_new, Ix2exc_new);
|
||||
|
||||
(*this).Set_to_Label (Return_State_Label(newdata, OriginStateIx2));
|
||||
|
||||
//cout << "Obtained label " << (*this).label << endl;
|
||||
}
|
||||
|
||||
void LiebLin_Bethe_State::Parity_Flip ()
|
||||
|
|
|
@ -24,14 +24,11 @@ namespace ABACUS {
|
|||
// RefState is used here to provide the c_int, L and N parameters.
|
||||
|
||||
LiebLin_Bethe_State Nplus1State(RefState.c_int, RefState.L, RefState.N + 1);
|
||||
//LiebLin_Bethe_State NState(RefState.c_int, RefState.L, RefState.N);
|
||||
LiebLin_Bethe_State Nmin1State(RefState.c_int, RefState.L, RefState.N - 1);
|
||||
|
||||
Nplus1State.Compute_All(true);
|
||||
//NState.Compute_All(true);
|
||||
Nmin1State.Compute_All(true);
|
||||
|
||||
//return(NState.E - Nmin1State.E);
|
||||
return(0.5 * (Nplus1State.E - Nmin1State.E));
|
||||
}
|
||||
|
||||
|
|
|
@ -19,10 +19,6 @@ using namespace ABACUS;
|
|||
|
||||
namespace ABACUS {
|
||||
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, LiebLin_Bethe_State& LeftState,
|
||||
// LiebLin_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState,
|
||||
// LiebLin_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState,
|
||||
LiebLin_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile)
|
||||
{
|
||||
|
@ -45,13 +41,12 @@ namespace ABACUS {
|
|||
else if (whichDSF == 'g')
|
||||
ME = real(exp(ln_Psi_ME (RefState, LeftState)));
|
||||
else if (whichDSF == 'q') // geometrical quench
|
||||
//ME_CX = (LiebLin_Twisted_ln_Overlap(1.0, RefState.lambdaoc, RefState.lnnorm, LeftState));
|
||||
//ME_CX = (LiebLin_ln_Overlap(RefState.lambdaoc, RefState.lnnorm, LeftState));
|
||||
ME_CX = LiebLin_ln_Overlap(LeftState.lambdaoc, LeftState.lnnorm, RefState);
|
||||
else if (whichDSF == 'B') { // BEC to finite c quench: g2(x=0)
|
||||
//ME_CX = exp(ln_Overlap_with_BEC (LeftState)); // overlap part
|
||||
ME_CX = exp(ln_Overlap_with_BEC (LeftState) - ln_Overlap_with_BEC (RefState)); // overlap part, relative to saddle-point state
|
||||
ME = real(exp(ln_g2_ME (RefState, LeftState))); // matrix element part
|
||||
// overlap part, relative to saddle-point state
|
||||
ME_CX = exp(ln_Overlap_with_BEC (LeftState) - ln_Overlap_with_BEC (RefState));
|
||||
// matrix element part
|
||||
ME = real(exp(ln_g2_ME (RefState, LeftState)));
|
||||
// The product is ME_CX * ME = e^{-\delta S_e} \langle \rho_{sp} | g2 (x=0) | \rho_{sp} + e \rangle
|
||||
// and is the first half of the t-dep expectation value formula coming from the Quench Action formalism
|
||||
}
|
||||
|
@ -71,7 +66,6 @@ namespace ABACUS {
|
|||
if (whichDSF == 'Z') {
|
||||
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
|
||||
<< LeftState.iK - RefState.iK
|
||||
//<< "\t" << LeftState.conv
|
||||
<< 0 << "\t" // This is the deviation, here always 0
|
||||
<< "\t" << LeftState.label;
|
||||
}
|
||||
|
@ -79,7 +73,6 @@ namespace ABACUS {
|
|||
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
|
||||
<< LeftState.iK - RefState.iK << "\t"
|
||||
<< real(ME_CX) << "\t" << imag(ME_CX) - twoPI * int(imag(ME_CX)/twoPI + 1.0e-10) << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< 0 << "\t" // This is the deviation, here always 0
|
||||
<< LeftState.label;
|
||||
}
|
||||
|
@ -87,11 +80,9 @@ namespace ABACUS {
|
|||
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
|
||||
<< LeftState.iK - RefState.iK << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< 0 << "\t" // This is the deviation, here always 0
|
||||
<< LeftState.label;
|
||||
DAT_outfile << "\t" << Momentum_Right_Excitations(LeftState) << "\t" << Momentum_Left_Excitations(LeftState);
|
||||
//cout << Momentum_Right_Excitations(LeftState) << "\t" << Momentum_Left_Excitations(LeftState);
|
||||
}
|
||||
else if (whichDSF == 'B') { // BEC to finite c > 0 quench; g2 (x=0)
|
||||
if (fabs(real(ME_CX) * ME) > 1.0e-100)
|
||||
|
@ -99,7 +90,6 @@ namespace ABACUS {
|
|||
<< LeftState.iK - RefState.iK << "\t"
|
||||
<< real(ME_CX) << "\t" // the overlap is always real
|
||||
<< ME << "\t"
|
||||
//<< 0 << "\t" // This is the deviation, here always 0 // omit this here
|
||||
<< LeftState.label;
|
||||
}
|
||||
else if (whichDSF == 'C') { // BEC to finite c, overlap sq
|
||||
|
@ -108,14 +98,12 @@ namespace ABACUS {
|
|||
<< LeftState.iK - RefState.iK << "\t"
|
||||
<< real(ME_CX) << "\t" // the overlap is always real
|
||||
<< ME << "\t"
|
||||
//<< 0 << "\t" // This is the deviation, here always 0 // omit this here
|
||||
<< LeftState.label;
|
||||
}
|
||||
else {
|
||||
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot << "\t"
|
||||
<< LeftState.iK - RefState.iK << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< 0 << "\t" // This is the deviation, here always 0
|
||||
<< LeftState.label;
|
||||
}
|
||||
|
@ -127,46 +115,18 @@ namespace ABACUS {
|
|||
data_value = 1.0/(1.0 + LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot);
|
||||
else if (whichDSF == 'd' || whichDSF == '1') {
|
||||
if (fixed_iK)
|
||||
/*
|
||||
// use omega * MEsq/iK^2
|
||||
//data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot)
|
||||
// MEsq/ABACUS::max(1, (LeftState.iK - RefState.iK) * (LeftState.iK - RefState.iK))
|
||||
//: 0.0;
|
||||
*/
|
||||
// Careful: use fabs(E) since this must also work with Tgt0 or arbitrary RefState DEPRECATED ++G_1, USE abs_data_value
|
||||
data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
|
||||
else if (!fixed_iK) // use ME if momentum in fundamental window -iK_UL <= iK <= iK_UL
|
||||
//data_value = abs(LeftState.iK - RefState.iK) <= RefState.Tableau[0].Ncols ? // this last nr is iK_UL
|
||||
//MEsq : 0.0;
|
||||
//data_value = (LeftState.iK - RefState.iK == 0 ? 1.0 : 2.0) * MEsq;
|
||||
//data_value = ME * ME;
|
||||
// use omega * MEsq/iK^2
|
||||
// Careful: use fabs(E) since this must also work with Tgt0 or arbitrary RefState DEPRECATED ++G_1, USE abs_data_value
|
||||
data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME/ABACUS::max(1, (LeftState.iK - RefState.iK) * (LeftState.iK - RefState.iK));
|
||||
else if (!fixed_iK)
|
||||
data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME
|
||||
/ABACUS::max(1, (LeftState.iK - RefState.iK) * (LeftState.iK - RefState.iK));
|
||||
}
|
||||
else if (whichDSF == 'g' || whichDSF == 'o') {
|
||||
if (fixed_iK)
|
||||
/*
|
||||
// use omega * MEsq/((k^2 - mu + 4 c N/L)/L)
|
||||
data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot)
|
||||
* MEsq/((((LeftState.K - RefState.K) * (LeftState.K - RefState.K) - Chem_Pot) + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L)
|
||||
: 0.0;
|
||||
*/
|
||||
// Careful: use fabs(E) since this must also work with Tgt0 or arbitrary RefState
|
||||
data_value = (LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
|
||||
else if (!fixed_iK) { // simply use MEsq if momentum in fundamental window -iK_UL <= iK <= iK_UL
|
||||
//data_value = abs(LeftState.iK - RefState.iK) <= RefState.Tableau[0].Ncols ? // this last nr is iK_UL
|
||||
//MEsq : 0.0;
|
||||
//data_value = (LeftState.iK - RefState.iK == 0 ? 1.0 : 2.0) * MEsq;
|
||||
else if (!fixed_iK) {
|
||||
data_value = ME * ME;
|
||||
//data_value = fabs(LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) * ME * ME;
|
||||
// In the case of whichDSF == 'o', the state with label (N-1)_0_ gives zero data_value. Force to 1.
|
||||
//if (whichDSF == 'o' && fabs(LeftState.E - RefState.E - (LeftState.N - RefState.N) * Chem_Pot) < 1.0e-10) data_value = 1.0;
|
||||
}
|
||||
}
|
||||
//else if (whichDSF == 'o')
|
||||
//data_value = abs(LeftState.iK - RefState.iK) <= RefState.Tableau[0].Ncols ? // this last nr is iK_UL
|
||||
//MEsq : 0.0;
|
||||
else if (whichDSF == 'q')
|
||||
data_value = exp(2.0 * real(ME_CX));
|
||||
else if (whichDSF == 'B')
|
||||
|
|
|
@ -30,13 +30,6 @@ namespace ABACUS {
|
|||
: nstates(nstates_req), state(Vect<LiebLin_Bethe_State>(RefState, nstates_req)), weight(1.0/nstates_req, nstates_req)
|
||||
{
|
||||
}
|
||||
/*
|
||||
LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (const LiebLin_Bethe_State& RefState, int nstates_req, const Vect<DP>& weight_ref)
|
||||
: nstates(nstates_req), state(Vect<LiebLin_Bethe_State>(RefState, nstates_req)), weight(weight_ref)
|
||||
{
|
||||
if (weight_ref.size() != nstates_req) ABACUSerror("Incompatible vector size in LiebLin_Diagonal_State_Ensemble constructor.");
|
||||
}
|
||||
*/
|
||||
|
||||
// Recursively go through all arbitrary-order type 2 descendents
|
||||
void Generate_type_2_descendents (LiebLin_Bethe_State& ActualState, int* ndesc_ptr, const LiebLin_Bethe_State& OriginState)
|
||||
|
@ -65,12 +58,11 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho, int nstates_req)
|
||||
//: nstates(nstates_req)
|
||||
LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho)
|
||||
{
|
||||
// This function returns a state ensemble matching the continuous density rho.
|
||||
// The logic closely resembles the one used in Discretized_LiebLin_Bethe_State.
|
||||
|
||||
//version with 4 states in ensemble
|
||||
|
||||
Root_Density x(rho.Npts, rho.lambdamax);
|
||||
|
@ -81,8 +73,6 @@ namespace ABACUS {
|
|||
x.value[ix] += 2.0 * rho.value[ip] * rho.dlambda[ip] * atan ((x.lambda[ix] - rho.lambda[ip])/c_int);
|
||||
}
|
||||
x.value[ix] /= 2.0*PI; //normalization
|
||||
|
||||
//cout << x.lambda[ix] << "\t" << x.value[ix] << "\t" << rho.lambda[ix] "\t" << rho.value[ix] <<endl;
|
||||
}
|
||||
|
||||
// Now carry on as per Discretized_LiebLin_Bethe_State:
|
||||
|
@ -111,7 +101,6 @@ namespace ABACUS {
|
|||
for (int i = 0; i < rho.Npts; ++i) {
|
||||
integral_prev = integral;
|
||||
integral += L * rho.value[i] * rho.dlambda[i];
|
||||
//cout << x.value[i] << "\t" << integral << endl;
|
||||
if (integral > Nfound + 0.5) {
|
||||
// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
|
||||
if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
|
||||
|
@ -120,7 +109,6 @@ namespace ABACUS {
|
|||
|
||||
else {
|
||||
// few variables to clarify the computations, they do not need to be vectors, not used outside this loop
|
||||
//Ix2_found[Nfound] = 2.0 * L * (x.value[i] * (integral - Nfound - 0.5) + x.value[i-1] * (Nfound + 0.5 - integral_prev))/(integral - integral_prev);
|
||||
Ix2_found[Nfound] = 2.0 * L * x.Return_Value(rho.lambda[i]);
|
||||
|
||||
Ix2_left = floor(Ix2_found[Nfound]);
|
||||
|
@ -146,7 +134,9 @@ namespace ABACUS {
|
|||
state[2].Ix2[Nfound] = Ix2_right;
|
||||
state[3].Ix2[Nfound] = Ix2_right;
|
||||
}
|
||||
else { //it's a kind of magic: the zeroth goes in whle the first goes out, the second goes left if the third goes right
|
||||
else {
|
||||
//it's a kind of magic: the zeroth goes in whle the first goes out,
|
||||
//the second goes left if the third goes right
|
||||
state[0].Ix2[Nfound] = Ix2_in;
|
||||
state[1].Ix2[Nfound] = Ix2_out;
|
||||
state[2+change].Ix2[Nfound] = Ix2_left;
|
||||
|
@ -157,9 +147,7 @@ namespace ABACUS {
|
|||
Nfound++;
|
||||
}
|
||||
}
|
||||
//cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
//fix state[3] and state[4]
|
||||
for(int i=0; i<N-1; ++i) {
|
||||
|
@ -184,658 +172,25 @@ namespace ABACUS {
|
|||
if(!all_Diff) {
|
||||
//check if the first two states are different
|
||||
if(state[0].Ix2 == state[1].Ix2)
|
||||
ABACUSerror("Cannot create 4 (nor 2) different states in LiebLin_Diagonal_State_Ensemble. Consider increasing system size");
|
||||
ABACUSerror("Cannot create 4 (nor 2) different states in LiebLin_Diagonal_State_Ensemble. "
|
||||
"Consider increasing system size");
|
||||
else {
|
||||
nstates = 2;
|
||||
weight[0] = 0.5;
|
||||
weight[1] = 0.5;
|
||||
}
|
||||
}
|
||||
//set the weights accordingly to the distance between the states.
|
||||
// int n_moves_2 = 0, n_moves_3 = 0;
|
||||
// for(int i=0; i < N; ++i) {
|
||||
// if (!state[0].Ix2.is_in(state[2].Ix2[i])) ++n_moves_2;
|
||||
// if (!state[0].Ix2.is_in(state[3].Ix2[i])) ++n_moves_3;
|
||||
// }
|
||||
//
|
||||
// n_moves_2 = min(n_moves_2, n_moves - n_moves_2);
|
||||
// n_moves_3 = min(n_moves_3, n_moves - n_moves_3);
|
||||
//
|
||||
// weight[2] *= 2.0*n_moves_2/n_moves;
|
||||
// weight[3] *= 2.0*n_moves_3/n_moves;
|
||||
//
|
||||
// DP sum_weight = weight[0] + weight[1] + weight[2] + weight[3];
|
||||
|
||||
for(int i=0; i<nstates; ++i) {
|
||||
//weight[i] /= sum_weight;
|
||||
state[i].Set_Label_from_Ix2(state[0].Ix2);
|
||||
state[i].Compute_All(true);
|
||||
}
|
||||
|
||||
|
||||
cout << weight[0] << "\t" << state[0].Ix2 << endl << weight[0] << "\t" << state[1].Ix2 << endl;// << state[2].Ix2 << endl << state[3].Ix2 << endl;
|
||||
cout << weight[0] << "\t" << state[0].Ix2 << endl << weight[0] << "\t" << state[1].Ix2 << endl;
|
||||
|
||||
return;
|
||||
|
||||
|
||||
//old working version but not enough to saturate +fsumrule
|
||||
/*
|
||||
Root_Density x = rho;
|
||||
for(int ix=0; ix<x.Npts; ++ix) {
|
||||
x.value[ix] = x.lambda[ix];
|
||||
for( int ip=0; ip<rho.Npts; ++ip) {
|
||||
x.value[ix] += 2.0 * rho.value[ip] * rho.dlambda[ip] * atan ((x.lambda[ix] - rho.lambda[ip])/c_int);
|
||||
}
|
||||
x.value[ix] /= 2.0*PI; //normalization
|
||||
}
|
||||
|
||||
// Now carry on as per Discretized_LiebLin_Bethe_State:
|
||||
// Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
|
||||
DP integral = 0.0;
|
||||
DP integral_prev = 0.0;
|
||||
int Nfound = 0;
|
||||
Vect<DP> Ix2_found(0.0, N);
|
||||
int Ix2_left, Ix2_right;
|
||||
Vect<int> Ix2(N);
|
||||
Vect<int> Ix2_uncertain(0, N);
|
||||
Vect<int> index_uncertain(0, N);
|
||||
int n_uncertain = 0, n_states_raw = 1;
|
||||
|
||||
for (int i = 0; i < rho.Npts; ++i) {
|
||||
integral_prev = integral;
|
||||
integral += L * rho.value[i] * rho.dlambda[i];
|
||||
//cout << x.value[i] << "\t" << integral << endl;
|
||||
if (integral > Nfound + 0.5) {
|
||||
// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
|
||||
if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
|
||||
ABACUSerror("The distribution of particles is too discontinous for discretisation");
|
||||
}
|
||||
|
||||
else {
|
||||
// few variables to clarify the computations, they do not need to be vectors, not used outside this loop
|
||||
Ix2_found[Nfound] = 2.0 * L * (x.value[i] * (integral - Nfound - 0.5) + x.value[i-1] * (Nfound + 0.5 - integral_prev))/(integral - integral_prev);
|
||||
|
||||
Ix2_left = floor(Ix2_found[Nfound]);
|
||||
Ix2_left -= (Ix2_left + N + 1)%2 ? 1 : 0; //adjust parity
|
||||
|
||||
Ix2_right = ceil(Ix2_found[Nfound]);
|
||||
Ix2_right += (Ix2_right + N + 1)%2 ? 1 : 0; //adjust parity
|
||||
|
||||
//cout << Ix2_found[Nfound] << "\t";
|
||||
|
||||
//choose the saddle point state and remember the uncertain choices
|
||||
if(Ix2_found[Nfound] - Ix2_left < 1) {
|
||||
Ix2[Nfound] = Ix2_left;
|
||||
if(Ix2_found[Nfound] - Ix2_left > 0.75) {
|
||||
Ix2_uncertain[n_uncertain] = -1;
|
||||
index_uncertain[n_uncertain] = Nfound;
|
||||
++n_uncertain;
|
||||
n_states_raw *= 2;
|
||||
}
|
||||
}
|
||||
else if (Ix2_right - Ix2_found[Nfound] < 1) {
|
||||
Ix2[Nfound] = Ix2_right;
|
||||
if(Ix2_right - Ix2_found[Nfound] > 0.75) {
|
||||
Ix2_uncertain[n_uncertain] = 1;
|
||||
index_uncertain[n_uncertain] = Nfound;
|
||||
++n_uncertain;
|
||||
n_states_raw *= 2;
|
||||
}
|
||||
}
|
||||
else ABACUSerror("Cannot deduce a quantum number from x(lambda)");
|
||||
Nfound++;
|
||||
}
|
||||
}
|
||||
//cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
//cout << Ix2 << endl;
|
||||
|
||||
// create ensamble of states and compute its weights with respect to exact Ix2 saddle point
|
||||
Vect<Vect<int> > Ix2states(Ix2, n_states_raw);
|
||||
Vect<DP> Ix2weight(0.0, n_states_raw);
|
||||
|
||||
// Ix2states[0] = Ix2;
|
||||
// Ix2weight[0] = ;
|
||||
int n_states_proper = 0;
|
||||
for(int i=0; i < n_states_raw; ++i) {
|
||||
//only symmetric modifications
|
||||
for(int mod_index = 0; mod_index<n_uncertain; ++mod_index) {
|
||||
if((i & (1 << mod_index)) >> mod_index != 0) {
|
||||
Ix2states[n_states_proper][index_uncertain[mod_index]] += (-2)*Ix2_uncertain[mod_index];
|
||||
////Ix2states[state_index][N - 1 - hole_position[mod_index]] += (2)*holes[hole_position[mod_index]];
|
||||
}
|
||||
}
|
||||
//check if it's a proper set of quantum numbers
|
||||
bool OK = true;
|
||||
for(int j=0; j<N-1; ++j) if(Ix2states[n_states_proper][j] == Ix2states[n_states_proper][j+1]) OK = false;
|
||||
|
||||
if(OK) {
|
||||
DP sum = 0;
|
||||
for(int j=0; j<N; ++j) sum += abs(Ix2_found[j] - Ix2states[n_states_proper][j]);
|
||||
Ix2weight[n_states_proper] = exp(-sum);
|
||||
n_states_proper++;
|
||||
}
|
||||
else Ix2states[n_states_proper] = Ix2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//sort the states in increasing weight order;
|
||||
Vect<int> index(0, n_states_raw);
|
||||
for (int nrs = 0; nrs < n_states_raw; ++nrs) index[nrs] = nrs;
|
||||
Ix2weight.QuickSort(index);
|
||||
|
||||
//cut the number of states if above 21 <- arbitrary number for now
|
||||
nstates = min(n_states_proper, 21);
|
||||
cout << n_states_raw << "\t" << n_states_proper << "\t" << nstates << endl;
|
||||
|
||||
//create ensamble of states with normalised weights and ordered accordingly
|
||||
LiebLin_Bethe_State rhostate(c_int, N, L);
|
||||
rhostate.Ix2 = Ix2;
|
||||
rhostate.Compute_All(true);
|
||||
|
||||
state = Vect<LiebLin_Bethe_State>(rhostate, nstates);
|
||||
weight = Vect<DP>(nstates);
|
||||
|
||||
DP sum_weight = 0.0;
|
||||
for(int i=0; i<nstates; ++i) {
|
||||
state[i].Ix2 = Ix2states[index[n_states_raw - i - 1]];
|
||||
state[i].Set_Label_from_Ix2 (state[0].Ix2);
|
||||
weight[i] = Ix2weight[n_states_raw - i - 1];
|
||||
sum_weight += weight[i];
|
||||
}
|
||||
|
||||
//renormalise
|
||||
for(int i=0; i<nstates; ++i) weight[i] /= sum_weight;
|
||||
|
||||
// for(int i=0; i<nstates; ++i) {
|
||||
// cout << weight[i] << "\t" << state[i].Ix2 << endl;
|
||||
// }
|
||||
|
||||
return;
|
||||
*/
|
||||
//cout << rho_t.value << endl;
|
||||
|
||||
// different attempts - to delete soon
|
||||
// ABACUSerror("Stop here.");
|
||||
/*
|
||||
|
||||
// This function returns a state ensemble matching the continuous density rho.
|
||||
// The logic closely resembles the one used in Discretized_LiebLin_Bethe_State.
|
||||
|
||||
// Now carry on as per Discretized_LiebLin_Bethe_State:
|
||||
// Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
|
||||
DP integral = 0.0;
|
||||
DP integral_prev = 0.0;
|
||||
int Nfound = 0;
|
||||
Vect<DP> lambda_found(0.0, 2*N);
|
||||
|
||||
for (int i = 0; i < rho.Npts; ++i) {
|
||||
integral_prev = integral;
|
||||
integral += L * rho.value[i] * rho.dlambda[i];
|
||||
//cout << x.value[i] << "\t" << integral << endl;
|
||||
if (integral > Nfound + 0.5) {
|
||||
cout << L*x.value[i] << "\t" << integral << endl;
|
||||
// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
|
||||
if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
|
||||
lambda_found[Nfound++] = 0.25 * (3.0 * rho.lambda[i-1] + rho.lambda[i]);
|
||||
lambda_found[Nfound++] = 0.25 * (rho.lambda[i-1] + 3.0 * rho.lambda[i]);
|
||||
}
|
||||
else {
|
||||
//lambda_found[Nfound] = rho.lambda[i];
|
||||
// Better: center the lambda_found between these points:
|
||||
//lambda_found[Nfound] = rho.lambda[i-1] + (rho.lambda[i] - rho.lambda[i-1]) * ((Nfound + 1.0) - integral_prev)/(integral - integral_prev);
|
||||
lambda_found[Nfound] = 0.5 * (rho.lambda[i-1] + rho.lambda[i]);
|
||||
Nfound++;
|
||||
}
|
||||
}
|
||||
//cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
|
||||
}
|
||||
//cout << "rho: " << rho.Npts << " points" << endl << rho.value << endl;
|
||||
//cout << "sym: " << rho.value[0] << " " << rho.value[rho.value.size() - 1]
|
||||
// << "\t" << rho.value[rho.value.size()/2] << " " << rho.value[rho.value.size()/2 + 1] << endl;
|
||||
//cout << "Found " << Nfound << " particles." << endl;
|
||||
//cout << "lambda_found = " << lambda_found << endl;
|
||||
|
||||
Vect<DP> lambda(N);
|
||||
// Fill up the found rapidities:
|
||||
for (int il = 0; il < ABACUS::min(N, Nfound); ++il) lambda[il] = lambda_found[il];
|
||||
// If there are missing ones, put them at the end; ideally, this should never be called
|
||||
for (int il = Nfound; il < N; ++il) lambda[il] = lambda_found[Nfound-1] + (il - Nfound + 1) * (lambda_found[Nfound-1] - lambda_found[Nfound-2]);
|
||||
|
||||
//cout << lambda << endl;
|
||||
*/
|
||||
//try a different method
|
||||
//first determine bins, that is intervals in lambda which contain a single rapidity
|
||||
/*
|
||||
Vect<int> lambda_bin(0.0, N+1);
|
||||
integral = 0.0;
|
||||
Nfound = 0;
|
||||
|
||||
lambda_bin[0] = 0;
|
||||
lambda_bin[N] = rho.Npts-1;
|
||||
for(int i=0; i<rho.Npts; ++i) {
|
||||
integral += L * rho.value[i] * rho.dlambda[i];
|
||||
if (integral > Nfound + 1.0) lambda_bin[++Nfound] = i - (rho.lambda[i]>0);
|
||||
}
|
||||
|
||||
//put rapidity at the mean value of the distribution inside the bin
|
||||
for(int ib=0; ib < N; ++ib) {
|
||||
lambda_found[ib] = 0.0;
|
||||
for(int i=lambda_bin[ib]; i<lambda_bin[ib+1]; ++i) lambda_found[ib] += L * rho.value[i] * rho.lambda[i] * rho.dlambda[i];
|
||||
}
|
||||
|
||||
//cout << lambda_found << endl;
|
||||
|
||||
for(int i=0; i<N; ++i) cout << L*lambda[i]/PI << "\t" << L*lambda_found[i]/PI << endl;
|
||||
|
||||
|
||||
ABACUSerror("Stop here.");
|
||||
*/
|
||||
/*
|
||||
// Calculate quantum numbers: 2\pi * (L lambda + \sum_j 2 atan((lambda - lambda_j)/c)) = I_j
|
||||
// Use rounding.
|
||||
Vect<DP> Ix2_exact(N);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
DP sum = 0.0;
|
||||
for (int j = 0; j < N; ++j) sum += 2.0 * atan((lambda[i] - lambda[j])/c_int);
|
||||
Ix2_exact[i] = (L * lambda[i] + sum)/PI;
|
||||
Ix2_left[i] = floor(Ix2_exact[i]);
|
||||
Ix2_left[i] -= (Ix2_left[i] + N + 1)%2 ? 1 : 0;
|
||||
Ix2_right[i] = ceil(Ix2_exact[i]);
|
||||
Ix2_right[i] += (Ix2_right[i] + N + 1)%2 ? 1 : 0;
|
||||
|
||||
//cout << Ix2_left[i] << "\t" << Ix2_exact[i] << "\t" << Ix2_right[i] << endl;
|
||||
//Ix2[i] = 2.0* int((L * lambda[i] + sum)/twoPI) + (N % 2) - 1;
|
||||
// For N is even/odd, we want to round off to the nearest odd/even integer.
|
||||
//Ix2[i] = 2.0 * floor((L* lambda[i] + sum)/twoPI + 0.5 * (N%2 ? 1 : 2)) + (N%2) - 1;
|
||||
}
|
||||
//cout << "Found quantum numbers " << endl << Ix2 << endl;
|
||||
*/
|
||||
|
||||
/*
|
||||
//create the reference state and mark possible hole positions
|
||||
Vect<int> Ix2(N);
|
||||
Vect<float> holes(0.0, N);
|
||||
for(int i=0; i < N; ++i) {
|
||||
if(Ix2_found[i] - Ix2_left[i] < 1) {
|
||||
Ix2[i] = Ix2_left[i];
|
||||
if(Ix2_found[i] - Ix2_left[i] > 0.75) holes[i] = -1;
|
||||
}
|
||||
else {
|
||||
Ix2[i] = Ix2_right[i];
|
||||
if(Ix2_right[i] - Ix2_found[i] > 0.75) holes[i] = 1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
// cout << endl << Ix2 << endl;
|
||||
// cout << endl << holes << endl;
|
||||
/*
|
||||
//count number of possible states
|
||||
int n = 0;
|
||||
for(int i=0; i < N; ++i) {
|
||||
if(holes[i] != 0) ++n;
|
||||
}
|
||||
int n_states_raw = 1;
|
||||
*/
|
||||
/* only symmetric modifications
|
||||
for(int i=0; i<0.5*n; ++i) n_states_raw *= 2.0; //we count only symmetric modiications
|
||||
|
||||
Vect<Vect<int> > Ix2states(Ix2, n_states_raw);
|
||||
|
||||
Vect<int> hole_position(0, 0.5*n);
|
||||
int hole_index = 0;
|
||||
for(int i=N/2 + N%2; i<N; ++i) {
|
||||
if(holes[i] != 0) hole_position[hole_index++] = i;
|
||||
}
|
||||
|
||||
|
||||
//create modifications, we use bit representation of integers between 0 and n_states-1 treating zero as no change and 1 as mutltiplication by -1
|
||||
int state_index = 1;
|
||||
for(int i=1; i < n_states_raw; ++i) {
|
||||
//only symmetric modifications
|
||||
for(int mod_index = 0; mod_index<0.5*n; ++mod_index) {
|
||||
if((i & (1 << mod_index)) >> mod_index != 0) {
|
||||
Ix2states[state_index][hole_position[mod_index]] += (-2)*holes[hole_position[mod_index]];
|
||||
Ix2states[state_index][N - 1 - hole_position[mod_index]] += (2)*holes[hole_position[mod_index]];
|
||||
}
|
||||
}
|
||||
//check if it's a proper set of quantum numbers
|
||||
bool OK = true;
|
||||
for(int j=0; j<N-1; ++j) if(Ix2states[state_index][j] == Ix2states[state_index][j+1]) OK = false;
|
||||
|
||||
if(OK) state_index++;
|
||||
else Ix2states[state_index] = Ix2;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
for(int i=0; i<n; ++i) n_states_raw *= 2.0; //we count all posibilities
|
||||
|
||||
Vect<Vect<int> > Ix2states(Ix2, n_states_raw);
|
||||
|
||||
Vect<int> hole_position(0, n);
|
||||
int hole_index = 0;
|
||||
for(int i=0; i<N; ++i) {
|
||||
if(holes[i] != 0) hole_position[hole_index++] = i;
|
||||
}
|
||||
|
||||
|
||||
//create modifications, we use bit representation of integers between 0 and n_states-1 treating zero as no change and 1 as mutltiplication by -1
|
||||
int state_index = 1;
|
||||
for(int i=1; i < n_states_raw; ++i) {
|
||||
//only symmetric modifications
|
||||
for(int mod_index = 0; mod_index<n; ++mod_index) {
|
||||
if((i & (1 << mod_index)) >> mod_index != 0) {
|
||||
Ix2states[state_index][hole_position[mod_index]] += (-2)*holes[hole_position[mod_index]];
|
||||
//Ix2states[state_index][N - 1 - hole_position[mod_index]] += (2)*holes[hole_position[mod_index]];
|
||||
}
|
||||
}
|
||||
//check if it's a proper set of quantum numbers
|
||||
bool OK = true;
|
||||
for(int j=0; j<N-1; ++j) if(Ix2states[state_index][j] == Ix2states[state_index][j+1]) OK = false;
|
||||
|
||||
if(OK) state_index++;
|
||||
else Ix2states[state_index] = Ix2;
|
||||
}
|
||||
|
||||
*/
|
||||
/*
|
||||
n_states_raw = state_index;
|
||||
// for(int i=0; i<n_states; ++i) cout << Ix2states[i] << endl;
|
||||
|
||||
LiebLin_Bethe_State rhostate(c_int, N, L);
|
||||
rhostate.Ix2 = Ix2;
|
||||
rhostate.Compute_All(true);
|
||||
|
||||
Vect<LiebLin_Bethe_State> state_raw = Vect<LiebLin_Bethe_State>(rhostate, n_states_raw);
|
||||
Vect<DP> weight_raw(0.0, n_states_raw);
|
||||
*/
|
||||
|
||||
/*
|
||||
DP energy_rho = 0;
|
||||
for (int i = 0; i < rho.Npts; ++i) {
|
||||
energy_rho += L * rho.value[i] * rho.dlambda[i] * rho.lambda[i] * rho.lambda[i];
|
||||
}
|
||||
|
||||
cout << energy_rho << endl;
|
||||
|
||||
DP energy_discrete = 0;
|
||||
for (int i=0; i < N; ++i) {
|
||||
energy_discrete += lambda[i] * lambda[i];
|
||||
}
|
||||
energy_discrete /= N;
|
||||
cout << energy_discrete;
|
||||
*/
|
||||
/*
|
||||
DP sum_weight_raw = 0.0;
|
||||
for(int i=0; i<n_states_raw; ++i) {
|
||||
//state_raw[i].Ix2 = Ix2states[i];
|
||||
//state_raw[i].Set_Label_from_Ix2 (state_raw[0].Ix2);
|
||||
//state_raw[i].Compute_All(true);
|
||||
DP sum = 0;
|
||||
for(int j=0; j<N; ++j) sum += fabs(Ix2states[i][j] - Ix2_found[j]);
|
||||
weight_raw[i] = exp(sum)/L;
|
||||
|
||||
sum_weight_raw += weight_raw[i];
|
||||
}
|
||||
|
||||
for(int i=0; i<n_states_raw; ++i) weight_raw[i] /= sum_weight_raw;
|
||||
|
||||
// Order the weights in decreasing value:
|
||||
Vect<int> index(n_states_raw);
|
||||
for (int nrs = 0; nrs < n_states_raw; ++nrs) index[nrs] = nrs;
|
||||
weight_raw.QuickSort(index);
|
||||
|
||||
//nstates = 0;
|
||||
//for(int i=0; i<n_states_raw; ++i) if (weight_raw[i] > 0.01) ++nstates;
|
||||
|
||||
nstates = ABACUS::min(n_states_raw, 21);
|
||||
|
||||
cout << nstates << endl;
|
||||
|
||||
state = Vect<LiebLin_Bethe_State>(rhostate, nstates);
|
||||
weight = Vect<DP>(nstates);
|
||||
|
||||
DP sum_weight = 0.0;
|
||||
for(int i=0; i<nstates; ++i) {
|
||||
state[i].Ix2 = Ix2states[index[i]];
|
||||
state[i].Set_Label_from_Ix2 (state[0].Ix2);
|
||||
weight[i] = weight_raw[index[i]];
|
||||
sum_weight += weight[i];
|
||||
}
|
||||
|
||||
//renormalise
|
||||
for(int i=0; i<nstates; ++i) weight[i] /= sum_weight;
|
||||
|
||||
for(int i=0; i<nstates; ++i) {
|
||||
cout << weight[i] << "\t" << state[i].Ix2 << endl;
|
||||
}
|
||||
*/
|
||||
//ABACUSerror("Stop here.");
|
||||
|
||||
// end of different attempts
|
||||
/*
|
||||
// Check that the quantum numbers are all distinct:
|
||||
bool allOK = false;
|
||||
while (!allOK) {
|
||||
for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1] && Ix2[i] < 0) Ix2[i] -= 2;
|
||||
for (int i = 1; i < N; ++i) if (Ix2[i] == Ix2[i-1] && Ix2[i] > 0) Ix2[i] += 2;
|
||||
allOK = true;
|
||||
for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1]) allOK = false;
|
||||
}
|
||||
//cout << "Found modified quantum numbers " << endl << Ix2 << endl;
|
||||
|
||||
LiebLin_Bethe_State rhostate(c_int, N, L);
|
||||
rhostate.Ix2 = Ix2;
|
||||
rhostate.Compute_All(true);
|
||||
//cout << "rapidities of state found: " << rhostate.lambda << endl;
|
||||
|
||||
// Until here, the code is identical to that in Discretized_LiebLin_Bethe_State.
|
||||
// Construct states in the vicinity by going through type 2 descendents recursively:
|
||||
int ndesc_type2 = 0;
|
||||
int* ndesc_type2_ptr = &ndesc_type2;
|
||||
Generate_type_2_descendents (rhostate, ndesc_type2_ptr, rhostate);
|
||||
|
||||
|
||||
cout << "Found " << ndesc_type2 << " descendents for state " << rhostate << endl;
|
||||
//ABACUSerror("Stop here...");
|
||||
|
||||
// Now try to construct states in the vicinity.
|
||||
int nrstates1mod = 1;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (i == 0 || Ix2[i-1] < Ix2[i] - 2) nrstates1mod++;
|
||||
if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) nrstates1mod++;
|
||||
}
|
||||
//if (nrstates1mod < nstates_req) ABACUSerror("nrstates1mod < nstates_req in LiebLin_Diagonal_State_Ensemble.");
|
||||
nstates = nrstates1mod;
|
||||
|
||||
Vect<Vect<int> > Ix2states1mod(nrstates1mod);
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) Ix2states1mod[nrs] = Vect<int> (N);
|
||||
|
||||
int nfound = 0;
|
||||
Ix2states1mod[nfound++] = Ix2; // this is the sp state
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (i == 0 || Ix2[i-1] < Ix2[i] - 2) {
|
||||
Ix2states1mod[nfound] = Ix2;
|
||||
Ix2states1mod[nfound++][i] -= 2;
|
||||
}
|
||||
if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) {
|
||||
Ix2states1mod[nfound] = Ix2;
|
||||
Ix2states1mod[nfound++][i] += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate the weight of all found states:
|
||||
Vect<DP> rawweight(nrstates1mod);
|
||||
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) {
|
||||
DP sumweight = 0.0;
|
||||
for (int i = 0; i < N; ++i) sumweight += fabs(Ix2states1mod[nrs][i] - Ix2_exact[i]);
|
||||
rawweight[nrs] = exp(-sumweight/log(L));
|
||||
}
|
||||
|
||||
// Order the weights in decreasing value:
|
||||
Vect<int> index(nrstates1mod);
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) index[nrs] = nrs;
|
||||
rawweight.QuickSort(index);
|
||||
|
||||
// Calculate weight normalization:
|
||||
DP weightnorm = 0.0;
|
||||
//for (int ns = 0; ns < nstates_req; ++ns) weightnorm += rawweight[nrstates1mod - 1 - ns];
|
||||
for (int ns = 0; ns < nstates; ++ns) weightnorm += rawweight[nrstates1mod - 1 - ns];
|
||||
|
||||
state = Vect<LiebLin_Bethe_State>(rhostate, nstates);
|
||||
weight = Vect<DP> (nstates);
|
||||
|
||||
for (int ns = 0; ns < nstates; ++ns) {
|
||||
weight[ns] = rawweight[nrstates1mod - 1 - ns]/weightnorm;
|
||||
state[ns].Ix2 = Ix2states1mod[index[nrstates1mod - 1 - ns] ];
|
||||
state[ns].Set_Label_from_Ix2 (rhostate.Ix2);
|
||||
state[ns].Compute_All(true);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
LiebLin_Diagonal_State_Ensemble::LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho, int nstates_req)
|
||||
: nstates(nstates_req)
|
||||
{
|
||||
// This function returns a state ensemble matching the continuous density rho.
|
||||
// The logic closely resembles the one used in Discretized_LiebLin_Bethe_State.
|
||||
|
||||
// Each `exact' (from rho) quantum number is matched to its two possible values,
|
||||
// assigning a probability to each according to the proximity of the quantum number values.
|
||||
|
||||
// The set is then ordered in energy, and split into nstates_req boxes from which one
|
||||
// representative is selected, and given the probability = sum of probabilities in the box.
|
||||
|
||||
|
||||
// Begin as per Discretized_LiebLin_Bethe_State, to find the saddle-point state.
|
||||
// Each time N \int_{-\infty}^\lambda d\lambda' \rho(\lambda') crosses a half integer, add a particle:
|
||||
DP integral = 0.0;
|
||||
DP integral_prev = 0.0;
|
||||
int Nfound = 0;
|
||||
Vect<DP> lambda_found(0.0, 2*N);
|
||||
|
||||
for (int i = 0; i < rho.Npts; ++i) {
|
||||
integral_prev = integral;
|
||||
integral += L * rho.value[i] * rho.dlambda[i];
|
||||
if (integral > Nfound + 0.5) {
|
||||
// Subtle error: if the rho is too discontinuous, i.e. if more than one rapidity is found, must correct for this.
|
||||
if (integral > Nfound + 1.5 && integral < Nfound + 2.5) { // found two rapidities
|
||||
lambda_found[Nfound++] = 0.25 * (3.0 * rho.lambda[i-1] + rho.lambda[i]);
|
||||
lambda_found[Nfound++] = 0.25 * (rho.lambda[i-1] + 3.0 * rho.lambda[i]);
|
||||
}
|
||||
else {
|
||||
//lambda_found[Nfound] = rho.lambda[i];
|
||||
// Better: center the lambda_found between these points:
|
||||
//lambda_found[Nfound] = rho.lambda[i-1] + (rho.lambda[i] - rho.lambda[i-1]) * ((Nfound + 1.0) - integral_prev)/(integral - integral_prev);
|
||||
lambda_found[Nfound] = 0.5 * (rho.lambda[i-1] + rho.lambda[i]);
|
||||
Nfound++;
|
||||
}
|
||||
}
|
||||
//cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl;
|
||||
}
|
||||
//cout << "rho: " << rho.Npts << " points" << endl << rho.value << endl;
|
||||
//cout << "sym: " << rho.value[0] << " " << rho.value[rho.value.size() - 1]
|
||||
// << "\t" << rho.value[rho.value.size()/2] << " " << rho.value[rho.value.size()/2 + 1] << endl;
|
||||
//cout << "Found " << Nfound << " particles." << endl;
|
||||
//cout << "lambda_found = " << lambda_found << endl;
|
||||
|
||||
Vect<DP> lambda(N);
|
||||
// Fill up the found rapidities:
|
||||
for (int il = 0; il < ABACUS::min(N, Nfound); ++il) lambda[il] = lambda_found[il];
|
||||
// If there are missing ones, put them at the end; ideally, this should never be called
|
||||
for (int il = Nfound; il < N; ++il) lambda[il] = lambda_found[Nfound-1] + (il - Nfound + 1) * (lambda_found[Nfound-1] - lambda_found[Nfound-2]);
|
||||
|
||||
// Calculate quantum numbers: 2\pi * (L lambda + \sum_j 2 atan((lambda - lambda_j)/c)) = I_j
|
||||
// Use rounding.
|
||||
Vect<DP> Ix2_exact(N);
|
||||
Vect<int> Ix2(N);
|
||||
for (int i = 0; i < N; ++i) {
|
||||
DP sum = 0.0;
|
||||
for (int j = 0; j < N; ++j) sum += 2.0 * atan((lambda[i] - lambda[j])/c_int);
|
||||
Ix2_exact[i] = (L * lambda[i] + sum)/PI;
|
||||
//Ix2[i] = 2.0* int((L * lambda[i] + sum)/twoPI) + (N % 2) - 1;
|
||||
// For N is even/odd, we want to round off to the nearest odd/even integer.
|
||||
Ix2[i] = 2.0 * floor((L* lambda[i] + sum)/twoPI + 0.5 * (N%2 ? 1 : 2)) + (N%2) - 1;
|
||||
}
|
||||
//cout << "Found quantum numbers " << endl << Ix2 << endl;
|
||||
|
||||
// Check that the quantum numbers are all distinct:
|
||||
bool allOK = false;
|
||||
while (!allOK) {
|
||||
for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1] && Ix2[i] < 0) Ix2[i] -= 2;
|
||||
for (int i = 1; i < N; ++i) if (Ix2[i] == Ix2[i-1] && Ix2[i] > 0) Ix2[i] += 2;
|
||||
allOK = true;
|
||||
for (int i = 0; i < N-1; ++i) if (Ix2[i] == Ix2[i+1]) allOK = false;
|
||||
}
|
||||
//cout << "Found modified quantum numbers " << endl << Ix2 << endl;
|
||||
|
||||
LiebLin_Bethe_State rhostate(c_int, N, L);
|
||||
rhostate.Ix2 = Ix2;
|
||||
rhostate.Compute_All(true);
|
||||
//cout << "rapidities of state found: " << rhostate.lambda << endl;
|
||||
|
||||
// Until here, the code is identical to that in Discretized_LiebLin_Bethe_State.
|
||||
|
||||
// Now try to construct states in the vicinity.
|
||||
int nrstates1mod = 1;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (i == 0 || Ix2[i-1] < Ix2[i] - 2) nrstates1mod++;
|
||||
if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) nrstates1mod++;
|
||||
}
|
||||
if (nrstates1mod < nstates_req) ABACUSerror("nrstates1mod < nstates_req in LiebLin_Diagonal_State_Ensemble.");
|
||||
|
||||
Vect<Vect<int> > Ix2states1mod(nrstates1mod);
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) Ix2states1mod[nrs] = Vect<int> (N);
|
||||
|
||||
int nfound = 0;
|
||||
Ix2states1mod[nfound++] = Ix2; // this is the sp state
|
||||
for (int i = 0; i < N; ++i) {
|
||||
if (i == 0 || Ix2[i-1] < Ix2[i] - 2) {
|
||||
Ix2states1mod[nfound] = Ix2;
|
||||
Ix2states1mod[nfound++][i] -= 2;
|
||||
}
|
||||
if (i == N-1 || Ix2[i+1] > Ix2[i] + 2) {
|
||||
Ix2states1mod[nfound] = Ix2;
|
||||
Ix2states1mod[nfound++][i] += 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate the weight of all found states:
|
||||
Vect<DP> rawweight(nrstates1mod);
|
||||
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) {
|
||||
DP sumweight = 0.0;
|
||||
for (int i = 0; i < N; ++i) sumweight += fabs(Ix2states1mod[nrs][i] - Ix2_exact[i]);
|
||||
rawweight[nrs] = exp(-sumweight/log(L));
|
||||
}
|
||||
|
||||
// Order the weights in decreasing value:
|
||||
Vect<int> index(nrstates1mod);
|
||||
for (int nrs = 0; nrs < nrstates1mod; ++nrs) index[nrs] = nrs;
|
||||
rawweight.QuickSort(index);
|
||||
|
||||
// Calculate weight normalization:
|
||||
DP weightnorm = 0.0;
|
||||
for (int ns = 0; ns < nstates_req; ++ns) weightnorm += rawweight[nrstates1mod - 1 - ns];
|
||||
|
||||
state = Vect<LiebLin_Bethe_State>(rhostate, nstates_req);
|
||||
weight = Vect<DP> (nstates_req);
|
||||
|
||||
for (int ns = 0; ns < nstates_req; ++ns) {
|
||||
weight[ns] = rawweight[nrstates1mod - 1 - ns]/weightnorm;
|
||||
state[ns].Ix2 = Ix2states1mod[index[nrstates1mod - 1 - ns] ];
|
||||
state[ns].Set_Label_from_Ix2 (rhostate.Ix2);
|
||||
state[ns].Compute_All(true);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
LiebLin_Diagonal_State_Ensemble& LiebLin_Diagonal_State_Ensemble::operator= (const LiebLin_Diagonal_State_Ensemble& rhs)
|
||||
{
|
||||
|
@ -858,7 +213,6 @@ namespace ABACUS {
|
|||
while (getline(infile, dummy)) ++nrlines;
|
||||
infile.close();
|
||||
|
||||
//cout << "Found " << nrlines << " lines in ens file." << endl;
|
||||
nstates = nrlines;
|
||||
LiebLin_Bethe_State examplestate (c_int, L, N);
|
||||
state = Vect<LiebLin_Bethe_State> (examplestate, nstates);
|
||||
|
@ -893,7 +247,6 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
|
||||
//LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT, int nstates_req)
|
||||
LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT)
|
||||
{
|
||||
// This function constructs a manifold of states around the thermal saddle-point.
|
||||
|
@ -915,7 +268,6 @@ namespace ABACUS {
|
|||
cout << "ebar: " << TBAsol.ebar << endl;
|
||||
|
||||
cout << ensemble.state[0].E << endl;
|
||||
//return(LiebLin_Diagonal_State_Ensemble (c_int, L, N, TBAsol.rho, nstates_req));
|
||||
return(ensemble);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,12 +20,10 @@ using namespace ABACUS;
|
|||
|
||||
namespace ABACUS {
|
||||
|
||||
//DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, bool fixed_iK, int iKneeded)
|
||||
DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
|
||||
{
|
||||
DP sumrule_factor = 1.0;
|
||||
|
||||
//if (!fixed_iK) {
|
||||
if (iKmin != iKmax) {
|
||||
if (whichDSF == 'Z') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'd' || whichDSF == '1') {
|
||||
|
@ -33,28 +31,15 @@ namespace ABACUS {
|
|||
// Here, we use a measure decreasing in K with K^2.
|
||||
// We sum up omega * MEsq/(iK^2) for all values of iKmin <= iK <= iKmax, discounting iK == 0 (where DSF vanishes)
|
||||
// We therefore have (N/L) x L^{-1} x (2\pi/L)^2 x (iKmax - iKmin + 1) = 4 \pi^2 x N x (iKmax - iKmin + 1)/L^4
|
||||
// Discounting iK == 0 (where DSF vanishes), if iKmin <= 0 && iKmax >= 0 (in which case 0 is containted in [iKmin, iKmax])
|
||||
// Discounting iK == 0 (where DSF vanishes),
|
||||
// if iKmin <= 0 && iKmax >= 0 (in which case 0 is containted in [iKmin, iKmax])
|
||||
sumrule_factor = (iKmin <= 0 && iKmax >= 0) ?
|
||||
(RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin))
|
||||
: (RefState.L * RefState.L * RefState.L * RefState.L)/(4.0 * PI * PI * RefState.N * (iKmax - iKmin + 1));
|
||||
|
||||
/*
|
||||
// Measure using the g2(0) + delta function: // DOES NOT WORK VERY WELL
|
||||
DP dE0_dc = LiebLin_dE0_dc (RefState.c_int, RefState.L, RefState.N);
|
||||
//sumrule_factor = 1.0/((dE0_dc + (2.0 * RefState.Tableau[0].Ncols + 1.0)*RefState.N/RefState.L)/RefState.L);
|
||||
// Assume that iKmin == 0 here:
|
||||
//sumrule_factor = 1.0/((dE0_dc + (2*iKmax + 1)*RefState.N/RefState.L)/RefState.L);
|
||||
// For iKmin != 0:
|
||||
sumrule_factor = 1.0/((dE0_dc + (iKmax - iKmin + 1)*RefState.N/RefState.L)/RefState.L);
|
||||
*/
|
||||
}
|
||||
// For the Green's function, it's the delta function \delta(x = 0) plus the density:
|
||||
//else if (whichDSF == 'g') sumrule_factor = 1.0/((2.0 * RefState.Tableau[0].Ncols + 1.0)/RefState.L + RefState.N/RefState.L);
|
||||
// Assume that iKmin == 0 here:
|
||||
//else if (whichDSF == 'g') sumrule_factor = 1.0/(2.0* iKmax + 1.0)/RefState.L + RefState.N/RefState.L);
|
||||
else if (whichDSF == 'g')
|
||||
sumrule_factor = 1.0/((abs(iKmax - iKmin) + 1.0)/RefState.L + RefState.N/RefState.L);
|
||||
//sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
|
||||
// For the one-body function, it's just the density:
|
||||
else if (whichDSF == 'o') sumrule_factor = RefState.L/RefState.N;
|
||||
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
||||
|
@ -63,21 +48,16 @@ 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 == 'd' || whichDSF == '1')
|
||||
//// We sum up omega * MEsq/(iK^2): this should give (1/L) x (N/L) x k^2 = N x (2\pi)^2/L^4
|
||||
//sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * RefState.N);
|
||||
// We sum up omega * MEsq
|
||||
//sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * iKneeded * iKneeded * RefState.N);
|
||||
sumrule_factor = pow(RefState.L, 4.0)/(4.0 * PI * PI * iKmax * iKmax * RefState.N);
|
||||
else if (whichDSF == 'g' || whichDSF == 'o') {
|
||||
// We sum up omega * MEsq
|
||||
//sumrule_factor = 1.0/((pow(twoPI * iKneeded/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
|
||||
sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
|
||||
sumrule_factor = 1.0/((pow(twoPI * iKmax/RefState.L, 2.0) - Chem_Pot
|
||||
+ 4.0 * RefState.c_int * RefState.N/RefState.L)/RefState.L);
|
||||
}
|
||||
//else if (whichDSF == 'o') sumrule_factor = RefState.L/RefState.N;
|
||||
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'B') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'C') sumrule_factor = 1.0;
|
||||
|
@ -87,7 +67,8 @@ namespace ABACUS {
|
|||
return(sumrule_factor);
|
||||
}
|
||||
|
||||
void Evaluate_F_Sumrule (char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax, const char* RAW_Cstr, const char* FSR_Cstr)
|
||||
void Evaluate_F_Sumrule (char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot,
|
||||
int iKmin, int iKmax, const char* RAW_Cstr, const char* FSR_Cstr)
|
||||
{
|
||||
|
||||
ifstream infile;
|
||||
|
@ -98,8 +79,6 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
// We run through the data file to check the f sumrule at each positive momenta:
|
||||
//int iK_UL = RefState.Tableau[0].Ncols; // this is iK_UL
|
||||
//Vect<DP> Sum_omega_MEsq(0.0, iK_UL + 1);
|
||||
Vect_DP Sum_omega_MEsq (0.0, iKmax - iKmin + 1);
|
||||
Vect_DP Sum_abs_omega_MEsq (0.0, iKmax - iKmin + 1);
|
||||
|
||||
|
@ -107,7 +86,6 @@ namespace ABACUS {
|
|||
|
||||
DP omega, ME;
|
||||
int iK;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
int nr, nl;
|
||||
|
@ -118,7 +96,6 @@ namespace ABACUS {
|
|||
nraw++;
|
||||
infile >> omega >> iK >> ME >> dev >> label;
|
||||
if (whichDSF == '1') infile >> nr >> nl;
|
||||
//if (iK > 0 && iK <= iK_UL) Sum_omega_MEsq[iK] += omega * MEsq;
|
||||
if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
|
||||
if (iK >= iKmin && iK <= iKmax) Sum_abs_omega_MEsq[iK - iKmin] += fabs(omega * ME * ME);
|
||||
Sum_MEsq += ME * ME;
|
||||
|
@ -126,25 +103,18 @@ namespace ABACUS {
|
|||
|
||||
infile.close();
|
||||
|
||||
//cout << "Read " << nraw << " entries in raw file." << endl;
|
||||
|
||||
ofstream outfile;
|
||||
outfile.open(FSR_Cstr);
|
||||
outfile.precision(16);
|
||||
|
||||
if (whichDSF == 'd' || whichDSF == '1') {
|
||||
/*
|
||||
outfile << 0 << "\t" << 1; // full saturation at k = 0 !
|
||||
for (int i = 1; i <= iK_UL; ++i)
|
||||
outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L * RefState.L
|
||||
* RefState.L * RefState.L/(4.0 * PI * PI * i * i * RefState.N);
|
||||
*/
|
||||
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
|
||||
if (i > iKmin) outfile << endl;
|
||||
//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N);
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
|
||||
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)
|
||||
/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
|
||||
// Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
|
||||
// so -iK is at index index(-iK) = -iK - iKmin
|
||||
// We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
|
||||
|
@ -155,16 +125,8 @@ namespace ABACUS {
|
|||
}
|
||||
}
|
||||
else if (whichDSF == 'g' || whichDSF == 'o') {
|
||||
/*
|
||||
for (int i = 0; i <= iK_UL; ++i)
|
||||
outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L
|
||||
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
//cout << "Sum_MEsq = " << Sum_MEsq << "\tN/L = " << RefState.N/RefState.L << endl;
|
||||
*/
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
if (i > iKmin) outfile << endl;
|
||||
//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
|
||||
///((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
|
||||
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
|
||||
<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
|
||||
|
@ -177,7 +139,8 @@ namespace ABACUS {
|
|||
|
||||
}
|
||||
|
||||
void Evaluate_F_Sumrule (string prefix, char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
|
||||
void Evaluate_F_Sumrule (string prefix, char whichDSF, const LiebLin_Bethe_State& RefState,
|
||||
DP Chem_Pot, int iKmin, int iKmax)
|
||||
{
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
|
@ -193,7 +156,8 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
// Using diagonal state ensemble:
|
||||
void Evaluate_F_Sumrule (char whichDSF, DP c_int, DP L, int N, DP kBT, int nstates_req, DP Chem_Pot, int iKmin, int iKmax, const char* FSR_Cstr)
|
||||
void Evaluate_F_Sumrule (char whichDSF, DP c_int, DP L, int N, DP kBT, int nstates_req,
|
||||
DP Chem_Pot, int iKmin, int iKmax, const char* FSR_Cstr)
|
||||
{
|
||||
|
||||
// We run through the data file to check the f sumrule at each positive momenta:
|
||||
|
@ -203,7 +167,6 @@ namespace ABACUS {
|
|||
|
||||
DP omega, ME;
|
||||
int iK;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
int nr, nl;
|
||||
|
@ -212,7 +175,6 @@ namespace ABACUS {
|
|||
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();
|
||||
|
@ -223,8 +185,8 @@ namespace ABACUS {
|
|||
|
||||
// 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);
|
||||
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";
|
||||
|
@ -240,7 +202,6 @@ namespace ABACUS {
|
|||
while (infile.peek() != EOF) {
|
||||
infile >> omega >> iK >> ME >> dev >> label;
|
||||
if (whichDSF == '1') infile >> nr >> nl;
|
||||
//if (iK > 0 && iK <= iK_UL) Sum_omega_MEsq[iK] += omega * MEsq;
|
||||
if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += ensemble.weight[ns] * omega * ME * ME;
|
||||
Sum_MEsq += ensemble.weight[ns] * ME * ME;
|
||||
}
|
||||
|
@ -255,16 +216,10 @@ namespace ABACUS {
|
|||
outfile.precision(16);
|
||||
|
||||
if (whichDSF == 'd' || whichDSF == '1') {
|
||||
/*
|
||||
outfile << 0 << "\t" << 1; // full saturation at k = 0 !
|
||||
for (int i = 1; i <= iK_UL; ++i)
|
||||
outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L * RefState.L
|
||||
* RefState.L * RefState.L/(4.0 * PI * PI * i * i * RefState.N);
|
||||
*/
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
if (i > iKmin) outfile << endl;
|
||||
//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N);
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * pow(RefState.L, 4.0)
|
||||
/(pow(2.0 * PI * ABACUS::max(abs(i), 1), 2.0) * RefState.N)
|
||||
// Include average of result at +iK and -iK in a third column: iK is at index index(iK) = iK - iKmin
|
||||
// so -iK is at index index(-iK) = -iK - iKmin
|
||||
// We can only use this index if it is >= 0 and < iKmax - iKmin + 1, otherwise third column is copy of second:
|
||||
|
@ -275,21 +230,14 @@ namespace ABACUS {
|
|||
}
|
||||
}
|
||||
else if (whichDSF == 'g' || whichDSF == 'o') {
|
||||
/*
|
||||
for (int i = 0; i <= iK_UL; ++i)
|
||||
outfile << endl << i << "\t" << Sum_omega_MEsq[i] * RefState.L
|
||||
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
//cout << "Sum_MEsq = " << Sum_MEsq << "\tN/L = " << RefState.N/RefState.L << endl;
|
||||
*/
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
if (i > iKmin) outfile << endl;
|
||||
//outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
|
||||
///((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i - iKmin] * RefState.L
|
||||
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L)
|
||||
<< "\t" << ((i + iKmin <= 0 && -i < iKmax + 1) ?
|
||||
0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin]) : Sum_omega_MEsq[i - iKmin])
|
||||
* RefState.L/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
0.5 * (Sum_omega_MEsq[i - iKmin] + Sum_omega_MEsq[-i - iKmin])
|
||||
: Sum_omega_MEsq[i - iKmin]) * RefState.L
|
||||
/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,116 +20,6 @@ using namespace ABACUS;
|
|||
namespace ABACUS {
|
||||
|
||||
|
||||
/*
|
||||
DP Entropy (LiebLin_Bethe_State& RefState, DP epsilon)
|
||||
{
|
||||
// This function calculates the entropy of a finite Lieb-Liniger state,
|
||||
// using the quantum number space particle and hole densities.
|
||||
|
||||
// The densities are a sum of Gaussians with width epsilon.
|
||||
|
||||
// We calculate \rho (x) and \rho_h (x) for x_j on a fine lattice.
|
||||
|
||||
int Ix2max = RefState.Ix2.max();
|
||||
int Ix2min = RefState.Ix2.min();
|
||||
|
||||
//cout << Ix2max << "\t" << Ix2min << endl;
|
||||
|
||||
// Give a bit of room for leftmost and rightmost particles Gaussians to attain asymptotic values:
|
||||
Ix2max += int(10.0 * RefState.L * epsilon);
|
||||
Ix2min -= int(10.0 * RefState.L * epsilon);
|
||||
|
||||
//cout << Ix2max << "\t" << Ix2min << endl;
|
||||
|
||||
DP xmax = Ix2max/(2.0* RefState.L);
|
||||
DP xmin = Ix2min/(2.0* RefState.L);
|
||||
|
||||
//xmax += 10.0* epsilon;
|
||||
//xmin -= 10.0* epsilon;
|
||||
|
||||
DP dx = 0.1/RefState.L;
|
||||
int Nptsx = int((xmax - xmin)/dx);
|
||||
|
||||
Vect<bool> occupied (false, (Ix2max - Ix2min)/2 + 1); // whether there is a particle or not
|
||||
for (int i = 0; i < RefState.N; ++i) occupied[(RefState.Ix2[i] - Ix2min)/2] = true;
|
||||
|
||||
Vect<double> rho(0.0, Nptsx);
|
||||
Vect<double> rhoh(0.0, Nptsx);
|
||||
|
||||
//cout << xmin << "\t" << xmax << "\t" << dx << "\t" << Nptsx << endl;
|
||||
|
||||
DP x;
|
||||
DP epsilonsq = epsilon * epsilon;
|
||||
DP twoepsilonsq = 2.0 * epsilon * epsilon;
|
||||
|
||||
//Vect<DP> xparticle(RefState.N);
|
||||
//for (int i = 0; i < RefState.N; ++i) xparticle[i] = RefState.Ix2[i]/(2.0* RefState.L);
|
||||
Vect<DP> xarray((Ix2max - Ix2min)/2 + 1);
|
||||
for (int i = 0; i < (Ix2max - Ix2min)/2 + 1; ++i) xarray[i] = (0.5*Ix2min + i)/RefState.L;
|
||||
|
||||
for (int ix = 0; ix < Nptsx; ++ix) {
|
||||
x = xmin + dx * (ix + 0.5);
|
||||
//for (int i = 0; i < RefState.N; ++i) rho[ix] += 1.0/((x - xparticle[i]) * (x - xparticle[i]) + epsilonsq);
|
||||
//rho[ix] *= epsilon/(PI * RefState.L);
|
||||
for (int i = 0; i < (Ix2max - Ix2min)/2 + 1; ++i) {
|
||||
// Using Gaussians:
|
||||
//if (occupied[i]) rho[ix] += exp(-(x - xarray[i]) * (x - xarray[i])/twoepsilonsq);
|
||||
//else rhoh[ix] += exp(-(x - xarray[i]) * (x - xarray[i])/twoepsilonsq);
|
||||
// Using Lorentzians:
|
||||
if (occupied[i]) rho[ix] += 1.0/((x - xarray[i]) * (x - xarray[i]) + epsilonsq);
|
||||
else rhoh[ix] += 1.0/((x - xarray[i]) * (x - xarray[i]) + epsilonsq);
|
||||
}
|
||||
//rho[ix] /= sqrt(twoPI) * epsilon * RefState.L;
|
||||
//rhoh[ix] /= sqrt(twoPI) * epsilon * RefState.L;
|
||||
rho[ix] *= epsilon/(PI * RefState.L);
|
||||
rhoh[ix] *= epsilon/(PI * RefState.L);
|
||||
//cout << ix << " x = " << x << "\trho = " << rho[ix] << "\trhoh = " << rhoh[ix] << "\trho + rhoh = " << rho[ix] + rhoh[ix] << endl;
|
||||
}
|
||||
|
||||
// Now calculate the entropy:
|
||||
complex<DP> entropy = 0.0;
|
||||
DP Deltax = log(RefState.L)/RefState.L;
|
||||
for (int ix = 0; ix < Nptsx; ++ix)
|
||||
//entropy -= ln_Gamma (1.0 + rho[ix]) + ln_Gamma (2.0 - rho[ix]); // This is ln (\rho_tot choose \rho) with \rho_tot = 1.
|
||||
entropy += ln_Gamma (RefState.L * (rho[ix] + rhoh[ix]) * Deltax + 1.0) - ln_Gamma(RefState.L * rho[ix] * Deltax + 1.0) - ln_Gamma (RefState.L * rhoh[ix] * Deltax + 1.0); // This is ln (\rho_tot choose \rho) with \rho_tot = 1.
|
||||
entropy *= dx/Deltax;
|
||||
|
||||
//cout << "Entropy found " << entropy << "\t" << real(entropy) << endl;
|
||||
|
||||
return(real(entropy));
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
DP Entropy_rho (LiebLin_Bethe_State& RefState, int Delta)
|
||||
{
|
||||
// This function calculates the discrete entropy of a finite Lieb-Liniger state,
|
||||
// counting the possible permutations within windows of fixed width.
|
||||
|
||||
// We assume that the quantum numbers are ordered.
|
||||
|
||||
// Calculate a density \rho_\Delta (x) for x_j on the lattice:
|
||||
|
||||
int iK_UL = ABACUS::max(RefState.Ix2[0], RefState.Ix2[RefState.N - 1]);
|
||||
|
||||
Vect<double> rhoD(0.0, 2* iK_UL);
|
||||
|
||||
int fourDeltasq = 4 * Delta * Delta;
|
||||
for (int ix = 0; ix < 2* iK_UL; ++ix) {
|
||||
// x = (-iK_UL + 1/2 + ix)/L
|
||||
for (int i = 0; i < RefState.N; ++i) rhoD[ix] += 1.0/((-2*iK_UL + 1 + 2*ix -RefState.Ix2[i]) * (-2*iK_UL + 1 + 2*ix -RefState.Ix2[i]) + fourDeltasq);
|
||||
rhoD[ix] *= 4.0 * Delta/PI;
|
||||
//cout << "x = " << (-iK_UL + 1/2 + ix)/RefState.L << "\trhoD = " << rhoD[ix] << endl;
|
||||
}
|
||||
|
||||
// Now calculate the entropy:
|
||||
DP entropy = 0.0;
|
||||
for (int ix = 0; ix < 2* iK_UL; ++ix)
|
||||
entropy -= rhoD[ix] * log(rhoD[ix]) + (1.0 - rhoD[ix]) * log(1.0 - rhoD[ix]);
|
||||
|
||||
return(entropy);
|
||||
}
|
||||
*/
|
||||
|
||||
DP Entropy_Fixed_Delta (LiebLin_Bethe_State& RefState, int Delta)
|
||||
{
|
||||
|
@ -139,13 +29,13 @@ namespace ABACUS {
|
|||
// We assume that the quantum numbers are ordered.
|
||||
|
||||
// Fill in vector of occupancies:
|
||||
int nrIs = (RefState.Ix2[RefState.N-1] - RefState.Ix2[0])/2 + 1 + 2*Delta; // assume Ix2 are ordered, leave space of Delta on both sides
|
||||
// assume Ix2 are ordered, leave space of Delta on both sides
|
||||
int nrIs = (RefState.Ix2[RefState.N-1] - RefState.Ix2[0])/2 + 1 + 2*Delta;
|
||||
Vect<int> occupancy(0, nrIs); // leave space of Delta on both sides
|
||||
for (int i = 0; i < RefState.N; ++i) occupancy[Delta + (RefState.Ix2[i] -RefState.Ix2[0])/2] = 1;
|
||||
// Check:
|
||||
int ncheck = 0;
|
||||
for (int i = 0; i < nrIs; ++i) if(occupancy[i] == 1) ncheck++;
|
||||
//cout << "Check occupancy: " << endl << occupancy << endl;
|
||||
if (ncheck != RefState.N) {
|
||||
cout << ncheck << "\t" << RefState.N << endl;
|
||||
ABACUSerror("Counting q numbers incorrectly in Entropy.");
|
||||
|
@ -154,10 +44,6 @@ namespace ABACUS {
|
|||
// Define some useful numbers:
|
||||
Vect_DP oneoverDeltalnchoose(Delta + 1);
|
||||
for (int i = 0; i <= Delta; ++i) oneoverDeltalnchoose[i] = ln_choose(Delta, i)/Delta;
|
||||
//Vect_DP oneoverDeltalnchoosecheck(Delta + 1);
|
||||
//for (int i = 0; i <= Delta; ++i) oneoverDeltalnchoosecheck[i] = log(DP(choose(Delta, i)))/Delta;
|
||||
//cout << oneoverDeltalnchoose << endl;
|
||||
//cout << oneoverDeltalnchoosecheck << endl;
|
||||
|
||||
// Compute entropy:
|
||||
DP entropy = 0.0;
|
||||
|
@ -185,288 +71,18 @@ namespace ABACUS {
|
|||
int Delta = int(log(RefState.L));
|
||||
return(Entropy (RefState, Delta));
|
||||
}
|
||||
/*
|
||||
DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, int Delta)
|
||||
{
|
||||
return(RefState.E - kBT * Entropy (RefState, Delta));
|
||||
}
|
||||
|
||||
DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, int Delta)
|
||||
{
|
||||
return(RefState.E - kBT * Entropy (RefState, Delta));
|
||||
}
|
||||
*/
|
||||
DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT)
|
||||
{
|
||||
return(RefState.E - kBT * Entropy (RefState));
|
||||
}
|
||||
|
||||
/*
|
||||
//LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, int Delta)
|
||||
LiebLin_Bethe_State Canonical_Saddle_Point_State_pre20110618 (DP c_int, DP L, int N, DP kBT, DP epsilon)
|
||||
{
|
||||
// This function returns the discretized state minimizing the canonical free energy
|
||||
// F = E - T S.
|
||||
|
||||
LiebLin_Bethe_State spstate(c_int, L, N);
|
||||
spstate.Compute_All (true);
|
||||
|
||||
if (kBT < 1.0e-3) return(spstate); // interpret as zero T case
|
||||
|
||||
LiebLin_Bethe_State spstateup = spstate;
|
||||
LiebLin_Bethe_State spstatedown = spstate;
|
||||
|
||||
bool converged = false;
|
||||
bool convergedati = false;
|
||||
|
||||
DP canfreeenstay, canfreeenup, canfreeendown;
|
||||
DP Estay, Eup, Edown;
|
||||
DP Sstay, Sup, Sdown;
|
||||
|
||||
while (!converged) {
|
||||
|
||||
spstate.Compute_All (false);
|
||||
converged = true; // set to false if we change anything
|
||||
|
||||
// If we can minimize the free energy by changing the quantum number, we do:
|
||||
// NOTE: we keep the state symmetric w/r to parity.
|
||||
|
||||
for (int i = 0; i < N/2; ++i) {
|
||||
// Try to increase or decrease this quantum number
|
||||
|
||||
convergedati = false;
|
||||
|
||||
while (!convergedati) {
|
||||
|
||||
convergedati = true; // set to false if we change anything
|
||||
|
||||
Estay = spstate.E;
|
||||
//Sstay = Entropy (spstate, Delta);
|
||||
Sstay = Entropy (spstate, epsilon);
|
||||
//canfreeenstay = Canonical_Free_Energy (spstate, kBT, Delta);
|
||||
canfreeenstay = Estay - kBT * Sstay;
|
||||
|
||||
spstateup = spstate;
|
||||
if (i == 0 || spstateup.Ix2[i-1] < spstateup.Ix2[i] - 2) {
|
||||
spstateup.Ix2[i] -= 2;
|
||||
spstateup.Ix2[N-1-i] += 2;
|
||||
spstateup.Compute_All(false);
|
||||
Eup = spstateup.E;
|
||||
//Sup = Entropy(spstateup, Delta);
|
||||
Sup = Entropy(spstateup, epsilon);
|
||||
//canfreeenup = Canonical_Free_Energy (spstateup, kBT, Delta);
|
||||
canfreeenup = Eup - kBT * Sup;
|
||||
}
|
||||
else canfreeenup = canfreeenstay + 1.0e-6;
|
||||
|
||||
spstatedown = spstate;
|
||||
if (spstatedown.Ix2[i+1] > spstatedown.Ix2[i] + 2) {
|
||||
spstatedown.Ix2[i] += 2;
|
||||
spstatedown.Ix2[N-1-i] -= 2;
|
||||
spstatedown.Compute_All(false);
|
||||
Edown = spstatedown.E;
|
||||
//Sdown = Entropy(spstatedown, Delta);
|
||||
Sdown = Entropy(spstatedown, epsilon);
|
||||
//canfreeendown = Canonical_Free_Energy (spstatedown, kBT, Delta);
|
||||
canfreeendown = Edown - kBT * Sdown;
|
||||
}
|
||||
else canfreeendown = canfreeenstay + 1.0e-6;
|
||||
|
||||
//cout << "i = " << i << "\t" << spstate.Ix2[i] << "\t\t" << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown
|
||||
// << "\t\t" << Estay << "\t" << Eup << "\t" << Edown << "\t\t" << Sstay << "\t" << Sup << "\t" << Sdown << endl;
|
||||
// Choose what to do:
|
||||
if (canfreeenup < canfreeenstay && canfreeendown < canfreeenstay)
|
||||
cout << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown << "\tWarning: unclear option for minimization." << endl;
|
||||
else if (canfreeenup < canfreeenstay) {
|
||||
spstate = spstateup;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
else if (canfreeendown < canfreeenstay) {
|
||||
spstate = spstatedown;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
// else do nothing.
|
||||
} // while !convergedati
|
||||
|
||||
} // for i
|
||||
} // while (!converged)
|
||||
|
||||
return(spstate);
|
||||
}
|
||||
*/
|
||||
|
||||
/* REMOVED FROM ++G_3 ONWARDS
|
||||
//LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, int Delta)
|
||||
//LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, DP epsilon)
|
||||
LiebLin_Bethe_State Canonical_Saddle_Point_State_pre8 (DP c_int, DP L, int N, DP kBT)
|
||||
{
|
||||
// This function returns the discretized state minimizing the canonical free energy
|
||||
// F = E - T S.
|
||||
|
||||
// Improvement on version pre20110618: allow for pairwise `in' and `out' movements
|
||||
// keeping the energy the same to order 1/L^2 but changing the entropy.
|
||||
|
||||
// The regulator Delta also has become an `internal' parameter.
|
||||
|
||||
LiebLin_Bethe_State spstate(c_int, L, N);
|
||||
spstate.Compute_All (true);
|
||||
|
||||
if (kBT < 1.0e-3) return(spstate); // interpret as zero T case
|
||||
|
||||
LiebLin_Bethe_State spstateup = spstate;
|
||||
LiebLin_Bethe_State spstatedown = spstate;
|
||||
LiebLin_Bethe_State spstatein = spstate;
|
||||
LiebLin_Bethe_State spstateout = spstate;
|
||||
|
||||
bool converged = false;
|
||||
bool convergedati = false;
|
||||
|
||||
DP canfreeenstay, canfreeenup, canfreeendown, canfreeenin, canfreeenout;
|
||||
DP Estay, Eup, Edown, Ein, Eout;
|
||||
DP Sstay, Sup, Sdown, Sin, Sout;
|
||||
Estay = 0.0; Eup = 0.0; Edown = 0.0; Ein = 0.0; Eout = 0.0;
|
||||
Sstay = 0.0; Sup = 0.0; Sdown = 0.0; Sin = 0.0; Sout = 0.0;
|
||||
|
||||
while (!converged) {
|
||||
|
||||
spstate.Compute_All (false);
|
||||
converged = true; // set to false if we change anything
|
||||
|
||||
// If we can minimize the free energy by changing the quantum number, we do:
|
||||
// NOTE: we keep the state symmetric w/r to parity.
|
||||
|
||||
for (int i = 0; i < N/2 - 1; ++i) {
|
||||
|
||||
// Try to increase or decrease the quantum numbers at i ,
|
||||
// or do an (approximately) energy-preserving move with i+1 (and parity pairs)
|
||||
// giving 5 possible options: stay same, (\pm 1, 0), (+1, -1), (-1, +1)
|
||||
|
||||
convergedati = false;
|
||||
|
||||
while (!convergedati) {
|
||||
|
||||
convergedati = true; // set to false if we change anything
|
||||
|
||||
Estay = spstate.E;
|
||||
Sstay = Entropy (spstate);
|
||||
//Sstay = Entropy (spstate, Delta);
|
||||
//Sstay = Entropy (spstate, epsilon);
|
||||
//canfreeenstay = Canonical_Free_Energy (spstate, kBT, Delta);
|
||||
canfreeenstay = Estay - kBT * Sstay;
|
||||
|
||||
spstateup = spstate;
|
||||
if (i == 0 || spstateup.Ix2[i-1] < spstateup.Ix2[i] - 2) {
|
||||
spstateup.Ix2[i] -= 2;
|
||||
spstateup.Ix2[N-1-i] += 2;
|
||||
spstateup.Compute_All(false);
|
||||
Eup = spstateup.E;
|
||||
Sup = Entropy(spstateup);
|
||||
//Sup = Entropy(spstateup, Delta);
|
||||
//Sup = Entropy(spstateup, epsilon);
|
||||
//canfreeenup = Canonical_Free_Energy (spstateup, kBT, Delta);
|
||||
canfreeenup = Eup - kBT * Sup;
|
||||
}
|
||||
else canfreeenup = canfreeenstay + 1.0e-6;
|
||||
|
||||
spstatedown = spstate;
|
||||
if (spstatedown.Ix2[i+1] > spstatedown.Ix2[i] + 2) {
|
||||
spstatedown.Ix2[i] += 2;
|
||||
spstatedown.Ix2[N-1-i] -= 2;
|
||||
spstatedown.Compute_All(false);
|
||||
Edown = spstatedown.E;
|
||||
Sdown = Entropy(spstatedown);
|
||||
//Sdown = Entropy(spstatedown, Delta);
|
||||
//Sdown = Entropy(spstatedown, epsilon);
|
||||
//canfreeendown = Canonical_Free_Energy (spstatedown, kBT, Delta);
|
||||
canfreeendown = Edown - kBT * Sdown;
|
||||
}
|
||||
else canfreeendown = canfreeenstay + 1.0e-6;
|
||||
|
||||
spstatein = spstate;
|
||||
if (spstatein.Ix2[i+1] > spstatein.Ix2[i] + 4) { // can move them closer
|
||||
spstatein.Ix2[i] += 2;
|
||||
spstatein.Ix2[i+1] -= 2;
|
||||
spstatein.Ix2[N-1-i] -= 2;
|
||||
spstatein.Ix2[N-1-i-1] += 2;
|
||||
spstatein.Compute_All(false);
|
||||
Ein = spstatein.E;
|
||||
Sin = Entropy(spstatein);
|
||||
//Sin = Entropy(spstatein, Delta);
|
||||
//Sin = Entropy(spstatein, epsilon);
|
||||
//canfreeenin = Canonical_Free_Energy (spstatein, kBT, Delta);
|
||||
canfreeenin = Ein - kBT * Sin;
|
||||
}
|
||||
else canfreeenin = canfreeenstay + 1.0e-6;
|
||||
|
||||
spstateout = spstate;
|
||||
if (i == 0 && spstateout.Ix2[1] + 2 < spstateout.Ix2[2]
|
||||
|| (i < N/2 - 1 && spstateout.Ix2[i] - 2 > spstateout.Ix2[i-1]
|
||||
&& spstateout.Ix2[i+1] + 2 < spstateout.Ix2[i+2])) { // can move them further apart
|
||||
spstateout.Ix2[i] -= 2;
|
||||
spstateout.Ix2[i+1] += 2;
|
||||
spstateout.Ix2[N-1-i] += 2;
|
||||
spstateout.Ix2[N-1-i-1] -= 2;
|
||||
spstateout.Compute_All(false);
|
||||
Eout = spstateout.E;
|
||||
Sout = Entropy(spstateout);
|
||||
//Sout = Entropy(spstateout, Delta);
|
||||
//Sout = Entropy(spstateout, epsilon);
|
||||
//canfreeenout = Canonical_Free_Energy (spstateout, kBT, Delta);
|
||||
canfreeenout = Eout - kBT * Sout;
|
||||
}
|
||||
else canfreeenout = canfreeenstay + 1.0e-6;
|
||||
|
||||
//cout << setprecision(8) << "i = " << i << "\t" << spstate.Ix2[i] << "\t" << spstate.Ix2[i+1] << "\t\t" << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown << "\t" << canfreeenin << "\t" << canfreeenout << endl;
|
||||
//cout << "\t\tE: " << Estay << "\t" << Eup << "\t" << Edown << "\t" << Ein << "\t" << Eout << endl;
|
||||
//cout << "\t\tS: " << Sstay << "\t" << Sup << "\t" << Sdown << "\t" << Sin << "\t" << Sout << endl;
|
||||
|
||||
// Choose what to do: find minimum,
|
||||
if (canfreeenstay < canfreeenup && canfreeenstay < canfreeendown && canfreeenstay < canfreeenin && canfreeenstay < canfreeenout) {
|
||||
// do nothing, convergetati is already true
|
||||
}
|
||||
else if (canfreeenup < canfreeenstay && canfreeenup < canfreeendown && canfreeenup < canfreeenin && canfreeenup < canfreeenout) {
|
||||
spstate = spstateup;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
else if (canfreeendown < canfreeenstay && canfreeendown < canfreeenup && canfreeendown < canfreeenin && canfreeendown < canfreeenout) {
|
||||
spstate = spstatedown;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
else if (canfreeenin < canfreeenstay && canfreeenin < canfreeenup && canfreeenin < canfreeendown && canfreeenin < canfreeenout) {
|
||||
spstate = spstatein;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
else if (canfreeenout < canfreeenstay && canfreeenout < canfreeenup && canfreeenout < canfreeendown && canfreeenout < canfreeenin) {
|
||||
spstate = spstateout;
|
||||
convergedati = false;
|
||||
converged = false;
|
||||
}
|
||||
else cout << canfreeenstay << "\t" << canfreeenup << "\t" << canfreeendown << "\t" << canfreeenin << "\t" << canfreeenout << "\tWarning: unclear option for minimization." << endl;
|
||||
|
||||
// else do nothing.
|
||||
} // while !convergedati
|
||||
|
||||
} // for i
|
||||
} // while (!converged)
|
||||
|
||||
//cout << "Number of holes between I's: " << endl;
|
||||
//for (int i = 0; i < N/2; ++i) cout << (spstate.Ix2[i+1] - spstate.Ix2[i])/2 - 1 << "\t";
|
||||
//cout << endl;
|
||||
|
||||
return(spstate);
|
||||
}
|
||||
*/
|
||||
|
||||
DP rho_of_lambdaoc_1 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta)
|
||||
{
|
||||
DP answer = 0.0;
|
||||
for (int i = 0; i < RefState.N; ++i)
|
||||
answer += atan((lambdaoc - RefState.lambdaoc[i])/delta + 0.5) - atan((lambdaoc - RefState.lambdaoc[i])/delta - 0.5);
|
||||
answer += atan((lambdaoc - RefState.lambdaoc[i])/delta + 0.5)
|
||||
- atan((lambdaoc - RefState.lambdaoc[i])/delta - 0.5);
|
||||
answer *= 1.0/(PI * delta * RefState.L);
|
||||
|
||||
return(answer);
|
||||
|
|
|
@ -51,14 +51,16 @@ namespace ABACUS {
|
|||
return(1.0/Fn_V (j, -sign, lstate_lambdaoc, rstate));
|
||||
}
|
||||
|
||||
complex<DP> LiebLin_Twisted_ln_Overlap (DP expbeta, Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
complex<DP> LiebLin_Twisted_ln_Overlap (DP expbeta, Vect<DP> lstate_lambdaoc,
|
||||
DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
Vect<complex<DP> > lstate_lambdaoc_CX(lstate_lambdaoc.size());
|
||||
for (int i = 0; i < lstate_lambdaoc.size(); ++i) lstate_lambdaoc_CX[i] = complex<DP>(lstate_lambdaoc[i]);
|
||||
return(LiebLin_Twisted_ln_Overlap (complex<DP>(expbeta), lstate_lambdaoc_CX, lstate_lnnorm, rstate));
|
||||
}
|
||||
|
||||
complex<DP> LiebLin_Twisted_ln_Overlap (complex<DP> expbeta, Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
complex<DP> LiebLin_Twisted_ln_Overlap (complex<DP> expbeta, Vect<complex<DP> > lstate_lambdaoc,
|
||||
DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
// Computes the log of the overlap between the left state and the Bethe rstate
|
||||
|
||||
|
@ -81,13 +83,13 @@ namespace ABACUS {
|
|||
Fn_Prod[a] = 1.0;
|
||||
for (int m = 0; m < rstate.N; ++m)
|
||||
if (m != a) Fn_Prod[a] *= (lstate_lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
|
||||
//rKern[a] = rstate.Kernel (a, p);
|
||||
rKern[a] = Kernel_Twisted (expbeta, rstate.lambdaoc[p] - rstate.lambdaoc[a]);
|
||||
}
|
||||
|
||||
for (int a = 0; a < rstate.N; ++a)
|
||||
for (int b = 0; b < rstate.N; ++b)
|
||||
one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + ((lstate_lambdaoc[a] - rstate.lambdaoc[a])/(1.0/Vplus_Nikita[a] - 1.0/Vminus_Nikita[a]))
|
||||
one_plus_U[a][b] = (a == b ? 1.0 : 0.0)
|
||||
+ ((lstate_lambdaoc[a] - rstate.lambdaoc[a])/(1.0/Vplus_Nikita[a] - 1.0/Vminus_Nikita[a]))
|
||||
* Fn_Prod[a] * (Kernel_Twisted(expbeta, rstate.lambdaoc[a] - rstate.lambdaoc[b]) - rKern[b]);
|
||||
|
||||
complex<DP> ln_ddalpha_sigma = lndet_LU_CX_dstry(one_plus_U);
|
||||
|
@ -101,16 +103,8 @@ namespace ABACUS {
|
|||
for (int b = 0; b < rstate.N; ++b)
|
||||
ln_prod_2 += log((lstate_lambdaoc[a] - rstate.lambdaoc[b] - II)/(rstate.lambdaoc[a] - lstate_lambdaoc[b]));
|
||||
|
||||
//cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << endl;
|
||||
//cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(Vplus[p] - Vminus[p]) << endl;
|
||||
|
||||
ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(Vplus_Nikita[p] - expbeta * Vminus_Nikita[p]);
|
||||
|
||||
//cout << "shift = " << (complex<DP>(rstate.N) * (lstate_lambdaoc[0] - rstate.lambdaoc[0])/twoPI) << "\tKout = " << Kout << "\texp(-II*Kout) = " << exp(-II * Kout)
|
||||
// << "\tlog(exp(-II * Kout) - 1.0) = " << log(exp(-II * Kout) - 1.0) << endl;
|
||||
//cout << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << lstate_lnnorm << endl << endl;
|
||||
|
||||
//return (log(1.0 - expbeta) + ln_ddalpha_sigma - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
return (log(1.0 - exp(-II * Kout)) + ln_ddalpha_sigma - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,8 @@ namespace ABACUS {
|
|||
for (int k = 0; k < N; ++k) {
|
||||
if (j == k) {
|
||||
sum_Kernel = 0.0;
|
||||
for (int kp = 0; kp < N; ++kp) if (j != kp) sum_Kernel += 2.0/((lambdaoc[j] - lambdaoc[kp]) * (lambdaoc[j] - lambdaoc[kp]) + 1.0);
|
||||
for (int kp = 0; kp < N; ++kp)
|
||||
if (j != kp) sum_Kernel += 2.0/((lambdaoc[j] - lambdaoc[kp]) * (lambdaoc[j] - lambdaoc[kp]) + 1.0);
|
||||
Gaudin[j][k] = cxL + sum_Kernel;
|
||||
}
|
||||
else Gaudin[j][k] = - 2.0/((lambdaoc[j] - lambdaoc[k]) * (lambdaoc[j] - lambdaoc[k]) + 1.0);
|
||||
|
|
|
@ -97,13 +97,11 @@ namespace ABACUS {
|
|||
lambda.Build_Reduced_Gaudin_Matrix ( Gaudin);
|
||||
lambda.Build_Reduced_BEC_Quench_Gaudin_Matrix (Gaudin_Quench);
|
||||
|
||||
//DP ln_prefactor = N/2.0 * log(2./fabs(c_int*L) ) + 0.5 * (N*log(N) - N + 0.5*log(2. * PI * N));
|
||||
|
||||
DP ln_prefactor = N/2.0 * log(2./(c_int*L) ) + 0.5 * real(ln_Gamma(complex<double>(N+1.0)));
|
||||
|
||||
for(int i =N/2; i<N; i ++) ln_prefactor -= log(fabs(lambda.lambdaoc[i ])) + 0.5*log( 1. + 4. * lambda.lambdaoc[i ]*lambda.lambdaoc[i ]) ;
|
||||
for(int i =N/2; i<N; i ++)
|
||||
ln_prefactor -= log(fabs(lambda.lambdaoc[i ])) + 0.5*log( 1. + 4. * lambda.lambdaoc[i ]*lambda.lambdaoc[i ]) ;
|
||||
|
||||
//cout << ln_prefactor << endl;
|
||||
return (ln_prefactor + real(lndet_LU_dstry(Gaudin_Quench)) - 0.5 * real(lndet_LU_dstry(Gaudin)));
|
||||
}
|
||||
|
||||
|
|
|
@ -19,22 +19,6 @@ using namespace std;
|
|||
using namespace ABACUS;
|
||||
|
||||
namespace ABACUS {
|
||||
/*
|
||||
complex<DP> Fn_V (int j, int sign, Vect<complex<DP> >& lstate_lambdaoc, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
complex<DP> result_num = 1.0;
|
||||
complex<DP> result_den = 1.0;
|
||||
|
||||
complex<DP> signcx = complex<DP>(sign);
|
||||
|
||||
for (int m = 0; m < rstate.N; ++m) {
|
||||
result_num *= (lstate_lambdaoc[m] - rstate.lambdaoc[j] + signcx * II);
|
||||
result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + signcx * II);
|
||||
}
|
||||
|
||||
return(result_num/result_den);
|
||||
}
|
||||
*/
|
||||
|
||||
complex<DP> LiebLin_ln_Overlap (Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
|
@ -77,26 +61,12 @@ namespace ABACUS {
|
|||
|
||||
for (int j = 0; j < rstate.N; ++j)
|
||||
for (int k = 0; k < rstate.N; ++k)
|
||||
//Omega[j][k] = exp(-II * rstate.cxL * lstate_lambdaoc[k] + ln_prod_plus[k] - ln_prod_ll_plus[k])
|
||||
//* (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] + II)))
|
||||
//- (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] - II)))
|
||||
//* exp(ln_prod_minus[k] - ln_prod_ll_plus[k]);
|
||||
Omega[j][k] = exp(-II * rstate.cxL * lstate_lambdaoc[k] - ln_prod_plus[k] + ln_prod_minus[k])
|
||||
* (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] - II)))
|
||||
- (II/((rstate.lambdaoc[j] - lstate_lambdaoc[k])*(rstate.lambdaoc[j] - lstate_lambdaoc[k] + II)));
|
||||
|
||||
|
||||
//for (int j = 0; j < rstate.N; ++j) {
|
||||
//for (int k = 0; k < rstate.N; ++k)
|
||||
//cout << Omega[j][k] << "\t";
|
||||
//cout << endl;
|
||||
//}
|
||||
|
||||
|
||||
complex<DP> lndetOmega = lndet_LU_CX_dstry(Omega);
|
||||
|
||||
//cout << "lndetOmega = " << lndetOmega << endl;
|
||||
|
||||
// Prefactors:
|
||||
complex<DP> ln_prod_d_mu = II * 0.5 * rstate.cxL * rstate.lambdaoc.sum();
|
||||
complex<DP> ln_prod_d_lambdaoc = II * 0.5 * rstate.cxL * lstate_lambdaoc.sum();
|
||||
|
@ -107,7 +77,6 @@ namespace ABACUS {
|
|||
for (int j = 0; j < rstate.N - 1; ++j)
|
||||
for (int k = j+1; k < rstate.N; ++k) {
|
||||
ln_prod_mu += log(rstate.lambdaoc[k] - rstate.lambdaoc[j]);
|
||||
//ln_prod_lambdaoc += log((lstate_lambdaoc[j] - lstate_lambdaoc[k] + II) * (lstate_lambdaoc[j] - lstate_lambdaoc[k] - II)/(lstate_lambdaoc[k] - lstate_lambdaoc[j]));
|
||||
ln_prod_lambdaoc += log(lstate_lambdaoc[k] - lstate_lambdaoc[j]);
|
||||
}
|
||||
|
||||
|
@ -115,72 +84,8 @@ namespace ABACUS {
|
|||
for (int k = 0; k < rstate.N; ++k)
|
||||
ln_prod_plusminus += log((rstate.lambdaoc[j] - lstate_lambdaoc[k] + II));
|
||||
|
||||
//cout << "ln_prod_mu " << ln_prod_mu << "\tln_prod_lambdaoc " << ln_prod_lambdaoc << "\tln_prod_plusminus " << ln_prod_plusminus
|
||||
// << "\texp1 " << exp(-ln_prod_mu - ln_prod_lambdaoc) << "\texp2 " << exp(ln_prod_plusminus) << endl;
|
||||
|
||||
//if (real(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu + ln_prod_lambdaoc + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm)) > 10.0) {
|
||||
//cout << ln_prod_d_mu << "\t" << ln_prod_d_lambdaoc << "\t" << -ln_prod_mu << "\t" << ln_prod_lambdaoc << "\t" << lndetOmega << "\t" << -0.5 * lstate_lnnorm << "\t" << -0.5 * rstate.lnnorm << endl; cout << ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu + ln_prod_lambdaoc + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm) << endl;
|
||||
//ABACUSerror("Overlap exceeds 1.");
|
||||
//}
|
||||
|
||||
//return(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu + ln_prod_lambdaoc + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
return(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu - ln_prod_lambdaoc + ln_prod_plusminus + lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
return(ln_prod_d_mu + ln_prod_d_lambdaoc - ln_prod_mu - ln_prod_lambdaoc + ln_prod_plusminus
|
||||
+ lndetOmega - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
}
|
||||
|
||||
/*
|
||||
// Incorrect version
|
||||
complex<DP> LiebLin_ln_Overlap (Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
// Computes the log of the overlap between the left state and the Bethe rstate
|
||||
|
||||
// If momentum difference is zero but states are different, then form factor is zero:
|
||||
|
||||
SQMat_CX one_plus_U (0.0, rstate.N);
|
||||
|
||||
Vect_CX Vplus (0.0, rstate.N); // contains V^+_j
|
||||
Vect_CX Vminus (0.0, rstate.N); // contains V^-_j
|
||||
Vect_CX Fn_Prod (0.0, rstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
|
||||
//Vect_DP rKern (0.0, rstate.N); // K(lambdaoc_j - lambdaoc_p)
|
||||
|
||||
//int p = 0;
|
||||
|
||||
complex<DP> Kout = lstate_lambdaoc.sum() - rstate.K;
|
||||
|
||||
for (int a = 0; a < rstate.N; ++a) {
|
||||
Vplus[a] = Fn_V (a, 1, lstate_lambdaoc, rstate);
|
||||
Vminus[a] = Fn_V (a, -1, lstate_lambdaoc, rstate);
|
||||
Fn_Prod[a] = 1.0;
|
||||
for (int m = 0; m < rstate.N; ++m)
|
||||
if (m != a) Fn_Prod[a] *= (lstate_lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
|
||||
//rKern[a] = rstate.Kernel (a, p);
|
||||
}
|
||||
|
||||
for (int a = 0; a < rstate.N; ++a)
|
||||
for (int b = 0; b < rstate.N; ++b)
|
||||
one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + II * ((lstate_lambdaoc[a] - rstate.lambdaoc[a])/(Vplus[a] - Vminus[a]))
|
||||
* Fn_Prod[a] * rstate.Kernel(a,b);
|
||||
|
||||
complex<DP> ln_ddalpha_sigma = lndet_LU_CX_dstry(one_plus_U);
|
||||
|
||||
complex<DP> ln_prod_V = 0.0;
|
||||
for (int a = 0; a < rstate.N; ++a) ln_prod_V += log(Vplus[a] - Vminus[a]);
|
||||
|
||||
complex<DP> ln_prod_2 = 0.0;
|
||||
for (int a = 0; a < rstate.N; ++a)
|
||||
for (int b = 0; b < rstate.N; ++b)
|
||||
ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate_lambdaoc[a] - rstate.lambdaoc[b]));
|
||||
|
||||
//cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << endl;
|
||||
cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << 0.5 * lstate_lnnorm << "\t" << 0.5 * rstate.lnnorm << endl;//- log(Vplus[p] - Vminus[p]) << endl;
|
||||
|
||||
ln_ddalpha_sigma += ln_prod_V + ln_prod_2;// - log(Vplus[p] - Vminus[p]);
|
||||
|
||||
//cout << "shift = " << (complex<DP>(rstate.N) * (lstate_lambdaoc[0] - rstate.lambdaoc[0])/twoPI) << "\tKout = " << Kout << "\texp(-II*Kout) = " << exp(-II * Kout)
|
||||
// << "\tlog(exp(-II * Kout) - 1.0) = " << log(exp(-II * Kout) - 1.0) << endl;
|
||||
//cout << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(Vplus[p] - Vminus[p]) << "\t" << lstate_lnnorm << endl << endl;
|
||||
|
||||
return (ln_ddalpha_sigma - 0.5 * (lstate_lnnorm + rstate.lnnorm));
|
||||
}
|
||||
*/
|
||||
|
||||
} // namespace ABACUS
|
||||
|
|
|
@ -21,17 +21,12 @@ namespace ABACUS {
|
|||
|
||||
complex<DP> Fn_V (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
//complex<DP> result_num = 1.0;
|
||||
//complex<DP> result_den = 1.0;
|
||||
complex<DP> result = 1.0;
|
||||
|
||||
for (int m = 0; m < lstate.N; ++m) {
|
||||
//result_num *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
//result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
result *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II)/(rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
}
|
||||
|
||||
//return(result_num/result_den);
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
@ -40,18 +35,14 @@ namespace ABACUS {
|
|||
// Computes the log of the density operator \rho(x = 0) matrix element between lstate and rstate.
|
||||
|
||||
// If we have lstate == rstate, density matrix element = N/L:
|
||||
|
||||
if (lstate.Ix2 == rstate.Ix2) return(log(lstate.N/lstate.L));
|
||||
|
||||
// If momentum difference is zero but states are different, then matrix element is zero:
|
||||
|
||||
else if (lstate.iK == rstate.iK) return(-200.0); // so exp(.) is zero
|
||||
|
||||
SQMat_DP one_plus_U (0.0, lstate.N);
|
||||
|
||||
Vect_CX Vplus (0.0, lstate.N); // contains V^+_j; V^-_j is the conjugate
|
||||
//Vect_DP Fn_Prod (0.0, lstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
|
||||
// From ABACUS++G_3 onwards: use logs to stabilize numerical values at small c, at the cost of execution speed.
|
||||
Vect_CX ln_Fn_Prod (0.0, lstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
|
||||
Vect_DP rKern (0.0, lstate.N); // K(lambdaoc_j - lambdaoc_(p == arbitrary))
|
||||
|
||||
|
@ -62,19 +53,17 @@ namespace ABACUS {
|
|||
|
||||
for (int a = 0; a < lstate.N; ++a) {
|
||||
Vplus[a] = Fn_V (a, lstate, rstate);
|
||||
//Fn_Prod[a] = 1.0;
|
||||
ln_Fn_Prod[a] = 0.0;;
|
||||
for (int m = 0; m < lstate.N; ++m)
|
||||
//if (m != a) Fn_Prod[a] *= (lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
|
||||
if (m != a) ln_Fn_Prod[a] += log(complex<DP>(lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]));
|
||||
if (m != a) ln_Fn_Prod[a] += log(complex<DP>(lstate.lambdaoc[m] - rstate.lambdaoc[a])
|
||||
/(rstate.lambdaoc[m] - rstate.lambdaoc[a]));
|
||||
rKern[a] = rstate.Kernel (a, p);
|
||||
}
|
||||
|
||||
for (int a = 0; a < lstate.N; ++a)
|
||||
for (int b = 0; b < lstate.N; ++b)
|
||||
one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + 0.5 * ((lstate.lambdaoc[a] - rstate.lambdaoc[a])/imag(Vplus[a]))
|
||||
//* Fn_Prod[a] * (rstate.Kernel(a,b) - rKern[b]);
|
||||
* real(exp(ln_Fn_Prod[a])) * (rstate.Kernel(a,b) - rKern[b]);
|
||||
* real(exp(ln_Fn_Prod[a])) * (rstate.Kernel(a,b) - rKern[b]); // BUGRISK: why real here?
|
||||
|
||||
complex<DP> ln_ddalpha_sigma = lndet_LU_dstry(one_plus_U);
|
||||
|
||||
|
@ -86,9 +75,6 @@ namespace ABACUS {
|
|||
for (int b = 0; b < lstate.N; ++b)
|
||||
ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate.lambdaoc[a] - rstate.lambdaoc[b]));
|
||||
|
||||
//cout << "ln_Fn_Prod = " << ln_Fn_Prod << endl;
|
||||
//cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << "\t" << - 0.5 * (lstate.lnnorm + rstate.lnnorm) << "\t" << ln_ddalpha_sigma + ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p])) - 0.5 * (lstate.lnnorm + rstate.lnnorm) << endl;
|
||||
|
||||
ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p]));
|
||||
|
||||
return (log(-II * Kout) + ln_ddalpha_sigma - 0.5 * (lstate.lnnorm + rstate.lnnorm));
|
||||
|
|
|
@ -66,16 +66,16 @@ namespace ABACUS {
|
|||
complex<DP> ln_prod_lambdaocsq_plus_one = 0.0;
|
||||
for (int a = 0; a < rstate.N - 1; ++a)
|
||||
for (int b = a; b < rstate.N; ++b)
|
||||
ln_prod_lambdaocsq_plus_one += log(complex<DP>((rstate.lambdaoc[a] - rstate.lambdaoc[b]) * (rstate.lambdaoc[a] - rstate.lambdaoc[b])) + 1.0);
|
||||
ln_prod_lambdaocsq_plus_one += log(complex<DP>((rstate.lambdaoc[a] - rstate.lambdaoc[b])
|
||||
* (rstate.lambdaoc[a] - rstate.lambdaoc[b])) + 1.0);
|
||||
|
||||
complex<DP> ln_prod_lambdaoca_min_mub = 0.0;
|
||||
for (int a = 0; a < rstate.N; ++a)
|
||||
for (int b = 0; b < lstate.N; ++b)
|
||||
ln_prod_lambdaoca_min_mub += log(complex<DP>(rstate.lambdaoc[a] - lstate.lambdaoc[b]));
|
||||
|
||||
//cout << endl << "Factors are " << ln_det_U_Psi << "\t" << ln_prod_lambdaocsq_plus_one << "\t" << ln_prod_lambdaoca_min_mub << endl;
|
||||
|
||||
return (ln_det_U_Psi + 0.5 * log(lstate.c_int) + ln_prod_lambdaocsq_plus_one - ln_prod_lambdaoca_min_mub - 0.5 * (lstate.lnnorm + rstate.lnnorm));
|
||||
return (ln_det_U_Psi + 0.5 * log(lstate.c_int) + ln_prod_lambdaocsq_plus_one - ln_prod_lambdaoca_min_mub
|
||||
- 0.5 * (lstate.lnnorm + rstate.lnnorm));
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace ABACUS
|
||||
|
|
|
@ -20,105 +20,15 @@ using namespace std;
|
|||
using namespace ABACUS;
|
||||
|
||||
namespace ABACUS {
|
||||
/*
|
||||
complex<DP> ln_g2_ME_old_jacopo (LiebLin_Bethe_State& mu, LiebLin_Bethe_State& lambda)
|
||||
{
|
||||
|
||||
if (mu.Ix2 == lambda.Ix2) return(-200.);
|
||||
|
||||
DP c_int = mu.c_int;
|
||||
|
||||
SQMat_CX G(lambda.N);
|
||||
SQMat_CX GpB(lambda.N);
|
||||
SQMat_CX B(lambda.N);
|
||||
|
||||
complex<DP> log_themp;
|
||||
complex<DP> lnprefactor = 0. ;
|
||||
|
||||
lnprefactor += 2.*log(c_int) ;
|
||||
|
||||
for(int j=0; j < mu.N; ++j){
|
||||
for(int k=0; k < j; ++k){
|
||||
lnprefactor -= log((mu.lambdaoc[j] - mu.lambdaoc[k]));
|
||||
lnprefactor -= log((lambda.lambdaoc[j] - lambda.lambdaoc[k]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(int j=0; j < mu.N; ++j){
|
||||
for(int k=0; k <mu.N; ++k){
|
||||
lnprefactor += log(mu.lambdaoc[j] - mu.lambdaoc[k] + II);
|
||||
}
|
||||
}
|
||||
|
||||
Vect_CX VVP (0.0, mu.N);
|
||||
Vect_CX VVM (0.0, mu.N);
|
||||
|
||||
//compute the vectors
|
||||
for(int j=0; j < mu.N; ++j) {
|
||||
log_themp = 0.;
|
||||
for(int k=0; k < mu.N; ++k) log_themp += log(mu.lambdaoc[j] - lambda.lambdaoc[k] + II) - log(mu.lambdaoc[j] - mu.lambdaoc[k] + II);
|
||||
VVP[j] = exp(log_themp);
|
||||
}
|
||||
|
||||
for(int j=0; j < mu.N; ++j) {
|
||||
log_themp = 0.;
|
||||
for(int k=0; k < mu.N; ++k) log_themp += log(mu.lambdaoc[j] - lambda.lambdaoc[k] - II) - log(mu.lambdaoc[j] - mu.lambdaoc[k] - II);
|
||||
VVM[j] = exp(log_themp);
|
||||
}
|
||||
|
||||
//compute the sum of determinants
|
||||
complex<DP> sum_n =0.;
|
||||
for(int n=0; n < mu.N; ++n) {
|
||||
// compute the matrices
|
||||
for (int a = 0; a < mu.N; ++a){
|
||||
for (int b = 0; b < mu.N; ++b){
|
||||
if(b == n){
|
||||
G[a][b] = 2.*II* lambda.lambdaoc[a];
|
||||
}
|
||||
else{
|
||||
G[a][b] = II*1./(lambda.lambdaoc[a] - mu.lambdaoc[b])*( VVP[b]*1.0/(mu.lambdaoc[b] - lambda.lambdaoc[a] + II) +
|
||||
VVM[b]*1.0/(mu.lambdaoc[b] - lambda.lambdaoc[a] - II) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 0; a < mu.N; ++a){
|
||||
for (int b = 0; b < mu.N; ++b){
|
||||
if(b == n){
|
||||
B[a][b] = 0.;
|
||||
}
|
||||
else{
|
||||
B[a][b] = II*1.0/(mu.lambdaoc[b] - mu.lambdaoc[n] - II) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 0; a < mu.N; ++a){
|
||||
for (int b = 0; b < mu.N; ++b){
|
||||
GpB[a][b] = G[a][b] + B[a][b];
|
||||
}
|
||||
}
|
||||
//finally add
|
||||
sum_n += exp( lndet_LU_CX(GpB) ) - exp(lndet_LU_CX(G) ) ;
|
||||
}
|
||||
|
||||
return(log(sum_n ) + lnprefactor - 0.5 * (mu.lnnorm + lambda.lnnorm));
|
||||
}
|
||||
*/
|
||||
complex<DP> Fn_V_g2 (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate)
|
||||
{
|
||||
//complex<DP> result_num = 1.0;
|
||||
//complex<DP> result_den = 1.0;
|
||||
complex<DP> result = 1.0;
|
||||
|
||||
for (int m = 0; m < lstate.N; ++m) {
|
||||
//result_num *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
//result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
result *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II)/(rstate.lambdaoc[m] - rstate.lambdaoc[j] + II);
|
||||
}
|
||||
|
||||
//return(result_num/result_den);
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
@ -128,44 +38,34 @@ namespace ABACUS {
|
|||
// Computes the log of the density operator \rho(x = 0) matrix element between lstate and rstate.
|
||||
|
||||
// If we have lstate == rstate, density matrix element = 0:
|
||||
|
||||
|
||||
if (lstate.Ix2 == rstate.Ix2) return(-200.);
|
||||
|
||||
|
||||
|
||||
|
||||
SQMat_DP one_plus_U (0.0, lstate.N);
|
||||
|
||||
Vect_CX Vplus (0.0, lstate.N); // contains V^+_j; V^-_j is the conjugate
|
||||
//Vect_DP Fn_Prod (0.0, lstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
|
||||
// From ABACUS++G_3 onwards: use logs to stabilize numerical values at small c, at the cost of execution speed.
|
||||
Vect_CX ln_Fn_Prod (0.0, lstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j)
|
||||
Vect_DP rKern (0.0, lstate.N); // K(lambdaoc_j - lambdaoc_(p == arbitrary))
|
||||
|
||||
//int p = 0;
|
||||
int p = rstate.N/2-1; // choice doesn't matter, see 1990_Slavnov_TMP_82 after (3.8). Choose rapidity around the middle.
|
||||
|
||||
|
||||
DP c_int = rstate.c_int;
|
||||
|
||||
DP Eout = log(pow(lstate.E - rstate.E,2.)) - (2)*log(c_int) - log(2*lstate.N);
|
||||
|
||||
for (int a = 0; a < lstate.N; ++a) {
|
||||
Vplus[a] = Fn_V_g2 (a, lstate, rstate);
|
||||
//Fn_Prod[a] = 1.0;
|
||||
ln_Fn_Prod[a] = 0.0;;
|
||||
for (int m = 0; m < lstate.N; ++m)
|
||||
//if (m != a) Fn_Prod[a] *= (lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]);
|
||||
if (m != a) ln_Fn_Prod[a] += log(complex<DP>(lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]));
|
||||
if (m != a) ln_Fn_Prod[a] += log(complex<DP>(lstate.lambdaoc[m] - rstate.lambdaoc[a])
|
||||
/(rstate.lambdaoc[m] - rstate.lambdaoc[a]));
|
||||
rKern[a] = rstate.Kernel (a, p);
|
||||
}
|
||||
|
||||
for (int a = 0; a < lstate.N; ++a)
|
||||
for (int b = 0; b < lstate.N; ++b)
|
||||
one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + 0.5 * 1./imag(Vplus[a])
|
||||
//* Fn_Prod[a] * (rstate.Kernel(a,b) - rKern[b]);
|
||||
* ((lstate.lambdaoc[a] - rstate.lambdaoc[a])*real(exp(ln_Fn_Prod[a])) * (rstate.Kernel(a,b) - rKern[b]) + rKern[b]);
|
||||
* ((lstate.lambdaoc[a] - rstate.lambdaoc[a])*real(exp(ln_Fn_Prod[a]))
|
||||
* (rstate.Kernel(a,b) - rKern[b]) + rKern[b]);
|
||||
|
||||
complex<DP> ln_ddalpha_sigma = lndet_LU_dstry(one_plus_U);
|
||||
|
||||
|
@ -177,16 +77,9 @@ namespace ABACUS {
|
|||
for (int b = 0; b < lstate.N; ++b)
|
||||
ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate.lambdaoc[a] - rstate.lambdaoc[b]));
|
||||
|
||||
//cout << "ln_Fn_Prod = " << ln_Fn_Prod << endl;
|
||||
//cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << "\t" << - 0.5 * (lstate.lnnorm + rstate.lnnorm) << "\t" << ln_ddalpha_sigma + ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p])) - 0.5 * (lstate.lnnorm + rstate.lnnorm) << endl;
|
||||
|
||||
ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p]));
|
||||
|
||||
return (log(II) + Eout + ln_ddalpha_sigma - 0.5 * (lstate.lnnorm + rstate.lnnorm));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace ABACUS
|
||||
|
|
|
@ -6,7 +6,6 @@ void ABACUS::ludcmp_CX (SQMat_CX& a, Vect_INT& indx, DP& d)
|
|||
const complex<DP> TINY = 1.0e-200;
|
||||
int i, j, k;
|
||||
int imax = 0;
|
||||
// DP big, dum, sum, temp;
|
||||
complex<DP> big, dum, sum, temp;
|
||||
|
||||
int n = a.size();
|
||||
|
@ -16,10 +15,8 @@ void ABACUS::ludcmp_CX (SQMat_CX& a, Vect_INT& indx, DP& d)
|
|||
for (i = 0; i < n; i++) {
|
||||
big = 0.0;
|
||||
for (j = 0; j < n; j++)
|
||||
// if ((temp = fabs(a[i][j])) > big) big = temp;
|
||||
if ((abs(temp = a[i][j])) > abs(big)) big = temp;
|
||||
//if ((norm(temp = a[i][j])) > norm(big)) big = temp;
|
||||
if (big == 0.0) throw Divide_by_zero(); //ABACUSerror("Singular matrix in routine ludcmp.");
|
||||
if (big == 0.0) throw Divide_by_zero();
|
||||
vv[i] = 1.0/big;
|
||||
}
|
||||
for (j = 0; j < n; j++) {
|
||||
|
@ -33,9 +30,7 @@ void ABACUS::ludcmp_CX (SQMat_CX& a, Vect_INT& indx, DP& d)
|
|||
sum = a[i][j];
|
||||
for (k = 0; k < j; k++) sum -= a[i][k] * a[k][j];
|
||||
a[i][j] = sum;
|
||||
// if ((dum = vv[i]*fabs(sum)) >= big) {
|
||||
if ((abs(dum = vv[i]*sum)) >= abs(big)) {
|
||||
//if ((norm(dum = vv[i]*sum)) >= norm(big)) {
|
||||
big = dum;
|
||||
imax = i;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ void ABACUS::tred2 (SQMat_DP& a, Vect_DP& d, Vect_DP& e)
|
|||
for (k = 0; k < l + 1; k++) scale += fabs(a[i][k]);
|
||||
if (scale == 0.0) e[i] = a[i][l];
|
||||
else {
|
||||
// scale = 1.0; // <- added this myself...
|
||||
for (k = 0; k < l + 1; k++) {
|
||||
a[i][k] /= scale;
|
||||
h += a[i][k] * a[i][k];
|
||||
|
|
|
@ -21,8 +21,10 @@ using namespace ABACUS;
|
|||
|
||||
namespace ABACUS {
|
||||
|
||||
void Build_DME_Matrix_Block_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required, bool symmetric_states, int iKmod,
|
||||
int weighing_option, int nrglabel_left_begin, int nrglabel_left_end, int nrglabel_right_begin, int nrglabel_right_end,
|
||||
void Build_DME_Matrix_Block_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax,
|
||||
int Nstates_required, bool symmetric_states, int iKmod,
|
||||
int weighing_option, int nrglabel_left_begin, int nrglabel_left_end,
|
||||
int nrglabel_right_begin, int nrglabel_right_end,
|
||||
int block_option, DP* DME_block_1, DP* DME_block_2, Vect_DP Kweight)
|
||||
{
|
||||
// Given a list of states produced by Select_States_for_NRG, this function
|
||||
|
@ -39,12 +41,18 @@ namespace ABACUS {
|
|||
// We assume the DME_blocks are already reserved in memory.
|
||||
// If !symmetric states, DME_block_2 doesn't need to be allocated.
|
||||
|
||||
if (nrglabel_left_begin < 0 || nrglabel_right_begin < 0) ABACUSerror("beginning nrglabels negative in Build_DME_Matrix_Block_for_NRG");
|
||||
if (nrglabel_left_end >= Nstates_required) ABACUSerror("nrglabel_left_end too large in Build_DME_Matric_Block_for_NRG");
|
||||
if (nrglabel_right_end >= Nstates_required) ABACUSerror("nrglabel_right_end too large in Build_DME_Matric_Block_for_NRG");
|
||||
if (nrglabel_left_begin < 0 || nrglabel_right_begin < 0)
|
||||
ABACUSerror("beginning nrglabels negative in Build_DME_Matrix_Block_for_NRG");
|
||||
if (nrglabel_left_end >= Nstates_required)
|
||||
ABACUSerror("nrglabel_left_end too large in Build_DME_Matric_Block_for_NRG");
|
||||
if (nrglabel_right_end >= Nstates_required)
|
||||
ABACUSerror("nrglabel_right_end too large in Build_DME_Matric_Block_for_NRG");
|
||||
|
||||
if (nrglabel_left_begin > nrglabel_left_end)
|
||||
ABACUSerror("nrglabels of left states improperly chosen in DME block builder.");
|
||||
if (nrglabel_right_begin > nrglabel_right_end)
|
||||
ABACUSerror("nrglabels of right states improperly chosen in DME block builder.");
|
||||
|
||||
if (nrglabel_left_begin > nrglabel_left_end) ABACUSerror("nrglabels of left states improperly chosen in DME block builder.");
|
||||
if (nrglabel_right_begin > nrglabel_right_end) ABACUSerror("nrglabels of right states improperly chosen in DME block builder.");
|
||||
// DME_block is a pointer of size row_l * col_l, where
|
||||
int block_row_length = nrglabel_right_end - nrglabel_right_begin + 1;
|
||||
int block_col_length = nrglabel_left_end - nrglabel_left_begin + 1;
|
||||
|
@ -77,7 +85,6 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
// Read the whole data file:
|
||||
//const int MAXDATA = 5000000;
|
||||
const int MAXDATA = ABACUS::max(nrglabel_left_end, nrglabel_right_end) + 10; // 10 for safety...
|
||||
|
||||
int* nrglabel = new int[MAXDATA];
|
||||
|
@ -123,7 +130,8 @@ namespace ABACUS {
|
|||
|
||||
Kept_States_left[nrglabel_left - nrglabel_left_begin] = Scanstate;
|
||||
|
||||
if (!Scanstate.conv) cout << "State of label " << label[nrglabel_left] << " did not converge after " << Scanstate.iter_Newton
|
||||
if (!Scanstate.conv)
|
||||
cout << "State of label " << label[nrglabel_left] << " did not converge after " << Scanstate.iter_Newton
|
||||
<< " Newton step; diffsq = " << Scanstate.diffsq << endl;
|
||||
} // for nrglabel_left
|
||||
|
||||
|
@ -136,7 +144,8 @@ namespace ABACUS {
|
|||
|
||||
Kept_States_right[nrglabel_right - nrglabel_right_begin] = Scanstate;
|
||||
|
||||
if (!Scanstate.conv) cout << "State of label " << label[nrglabel_right] << " did not converge after " << Scanstate.iter_Newton
|
||||
if (!Scanstate.conv)
|
||||
cout << "State of label " << label[nrglabel_right] << " did not converge after " << Scanstate.iter_Newton
|
||||
<< " Newton step; diffsq = " << Scanstate.diffsq << endl;
|
||||
} // for nrglabel_left
|
||||
|
||||
|
@ -147,7 +156,6 @@ namespace ABACUS {
|
|||
for (int lr = 0; lr < block_row_length; ++lr) {
|
||||
|
||||
if (Kept_States_left[ll].conv && Kept_States_right[lr].conv
|
||||
//&& abs(Kept_States[il].iK - Kept_States[ir].iK) % iKmod == 0)
|
||||
&& abs(Kept_States_left[ll].iK) % iKmod == 0
|
||||
&& abs(Kept_States_right[lr].iK) % iKmod == 0) {
|
||||
|
||||
|
@ -176,15 +184,19 @@ namespace ABACUS {
|
|||
|
||||
if (block_option == 1) {
|
||||
DME_block_1[ll* block_row_length + lr] =
|
||||
(Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
|
||||
+ Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate))));
|
||||
(Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
|
||||
* real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
|
||||
+ Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
|
||||
* real(exp(ln_Density_ME (Kept_States_left[ll], PRstate))));
|
||||
// We don't do anything with block 2, we don't even assume it's been allocated.
|
||||
}
|
||||
else if (block_option == 2) {
|
||||
DME_block_1[ll* block_row_length + lr] =
|
||||
Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
|
||||
Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
|
||||
* real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
|
||||
DME_block_2[ll* block_row_length + lr] =
|
||||
Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate)));
|
||||
Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
|
||||
* real(exp(ln_Density_ME (Kept_States_left[ll], PRstate)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,15 +206,19 @@ namespace ABACUS {
|
|||
|
||||
if (block_option == 1) {
|
||||
DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
|
||||
(Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
|
||||
+ Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate))));
|
||||
(Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
|
||||
* real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
|
||||
+ Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
|
||||
* real(exp(ln_Density_ME (Kept_States_left[ll], PRstate))));
|
||||
// We don't do anything with block 2, we don't even assume it's been allocated.
|
||||
}
|
||||
else if (block_option == 2) {
|
||||
DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
|
||||
Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
|
||||
Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
|
||||
* real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
|
||||
DME_block_2[ll* block_row_length + lr] = sqrt(0.5) *
|
||||
Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], PRstate)));
|
||||
Kweight[abs(Kept_States_left[ll].iK - PRstate.iK)]
|
||||
* real(exp(ln_Density_ME (Kept_States_left[ll], PRstate)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,15 +228,19 @@ namespace ABACUS {
|
|||
|
||||
if (block_option == 1) {
|
||||
DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
|
||||
(Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
|
||||
+ Kweight[abs(PLstate.iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (PLstate, Kept_States_right[lr]))));
|
||||
(Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
|
||||
* real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])))
|
||||
+ Kweight[abs(PLstate.iK - Kept_States_right[lr].iK)]
|
||||
* real(exp(ln_Density_ME (PLstate, Kept_States_right[lr]))));
|
||||
// We don't do anything with block 2, we don't even assume it's been allocated.
|
||||
}
|
||||
else if (block_option == 2) {
|
||||
DME_block_1[ll* block_row_length + lr] = sqrt(0.5) *
|
||||
Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
|
||||
Kweight[abs(Kept_States_left[ll].iK - Kept_States_right[lr].iK)]
|
||||
* real(exp(ln_Density_ME (Kept_States_left[ll], Kept_States_right[lr])));
|
||||
DME_block_2[ll* block_row_length + lr] = sqrt(0.5) *
|
||||
Kweight[abs(PLstate.iK - Kept_States_right[lr].iK)] * real(exp(ln_Density_ME (PLstate, Kept_States_right[lr])));
|
||||
Kweight[abs(PLstate.iK - Kept_States_right[lr].iK)]
|
||||
* real(exp(ln_Density_ME (PLstate, Kept_States_right[lr])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,16 +249,13 @@ namespace ABACUS {
|
|||
|
||||
else {
|
||||
DME_block_1[ll* block_row_length + lr] = 0.0;
|
||||
if (symmetric_states && block_option == 2) DME_block_2[ll* block_row_length + lr] = 0.0; // condition, to prevent segfault if DME_block_2 not allocated.
|
||||
// condition, to prevent segfault if DME_block_2 not allocated.
|
||||
if (symmetric_states && block_option == 2) DME_block_2[ll* block_row_length + lr] = 0.0;
|
||||
}
|
||||
|
||||
//cout << ll << "\t" << lr << "\t" << DME_block[ll* block_row_length + lr] << endl;
|
||||
|
||||
} // for lr
|
||||
} // for ll
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ABACUS
|
||||
|
|
|
@ -43,6 +43,4 @@ namespace ABACUS {
|
|||
return(value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace ABACUS
|
||||
|
|
|
@ -22,12 +22,8 @@ namespace ABACUS {
|
|||
|
||||
DP Estimate_Contribution_of_Single_ph_Annihilation_Path_to_2nd_Order_PT (LiebLin_Bethe_State& TopState,
|
||||
LiebLin_Bethe_State& GroundState,
|
||||
//Vect_DP Weight_integral)
|
||||
Vect<complex <DP> >& FT_of_potential)
|
||||
{
|
||||
//cout << TopState.label << "\t" << GroundState.label << endl;
|
||||
//cout << TopState.lambdaoc << endl;
|
||||
|
||||
DP contrib_estimate = 0.0;
|
||||
|
||||
// Define OriginIx2 for labelling:
|
||||
|
@ -49,8 +45,6 @@ namespace ABACUS {
|
|||
int nr_cont = 0;
|
||||
|
||||
// Add first-order PT contribution, and 2nd order from ground state (V_{00} == 1)
|
||||
//contrib_estimate += Weight_integral[Weight_integral.size()/2 + (TopState.iK - GroundState.iK)]
|
||||
//* (densityME/(GroundState.E - TopState.E)) * (1.0 - (GroundState.N/GroundState.L)/(GroundState.E - TopState.E));
|
||||
contrib_estimate += abs(FT_of_potential[FT_of_potential.size()/2 + (TopState.iK - GroundState.iK)]
|
||||
* (densityME/(GroundState.E - TopState.E))
|
||||
* (1.0 - (GroundState.N/GroundState.L)/(GroundState.E - TopState.E)));
|
||||
|
@ -58,10 +52,6 @@ namespace ABACUS {
|
|||
nr_cont++;
|
||||
|
||||
// Add second order PT contribution coming from TopState:
|
||||
//contrib_estimate += Weight_integral[Weight_integral.size()/2 + 0]
|
||||
//* Weight_integral[Weight_integral.size()/2 + (TopState.iK - GroundState.iK)]
|
||||
//* 1.0 * densityME * (GroundState.N/GroundState.L) // 1.0 is V_{TopState, TopState}
|
||||
///((GroundState.E - TopState.E) * (GroundState.E - TopState.E));
|
||||
contrib_estimate += abs(FT_of_potential[FT_of_potential.size()/2 + 0]
|
||||
* FT_of_potential[FT_of_potential.size()/2 + (TopState.iK - GroundState.iK)]
|
||||
* 1.0 * densityME * (GroundState.N/GroundState.L) // 1.0 is V_{TopState, TopState}
|
||||
|
@ -69,32 +59,20 @@ namespace ABACUS {
|
|||
|
||||
nr_cont++;
|
||||
|
||||
//cout << "Here b" << endl;
|
||||
|
||||
// Now add 2nd order terms coming from single particle-hole annihilation paths:
|
||||
// this is only to be included for states with at least 4 excitations (2 ph pairs)
|
||||
|
||||
if (nphpairs >= 2) {
|
||||
|
||||
for (int ipart = 0; ipart < nphpairs; ++ipart) {
|
||||
for (int ihole = 0; ihole < nphpairs; ++ihole) {
|
||||
|
||||
LiebLin_Bethe_State DescendedState = TopState;
|
||||
//cout << "Here 2a" << "\tipart " << ipart << "\tihole " << ihole << " out of " << nphpairs << " nphpairs, label " << TopState.label << endl;
|
||||
//cout << "TopState.Ix2 " << TopState.Ix2 << endl;
|
||||
//cout << "DescendedIx2 " << DescendedState.Ix2 << endl;
|
||||
DescendedState.Annihilate_ph_pair(ipart, ihole, OriginIx2);
|
||||
DescendedState.Compute_All(true);
|
||||
//cout << "DescendedIx2 " << DescendedState.Ix2 << endl;
|
||||
|
||||
DP densityME_top_desc = real(exp(ln_Density_ME (TopState, DescendedState)));
|
||||
DP densityME_desc_ground = real(exp(ln_Density_ME (DescendedState, GroundState)));
|
||||
|
||||
//contrib_estimate += Weight_integral[Weight_integral.size()/2 + (TopState.iK - DescendedState.iK)]
|
||||
//* Weight_integral[Weight_integral.size()/2 + (DescendedState.iK - GroundState.iK)]
|
||||
//* densityME_top_desc * densityME_desc_ground
|
||||
///((GroundState.E - TopState.E) * (GroundState.E - DescendedState.E));
|
||||
|
||||
// if intermediate state has momentum within allowable window, OK, otherwise discard contribution:
|
||||
if (abs(TopState.iK - DescendedState.iK) < FT_of_potential.size()/2 &&
|
||||
abs(DescendedState.iK - GroundState.iK) < FT_of_potential.size()/2) {
|
||||
|
@ -112,21 +90,12 @@ namespace ABACUS {
|
|||
for (int ihole2 = ihole; ihole2 < nphpairs - 1; ++ihole2) {
|
||||
|
||||
LiebLin_Bethe_State DescendedState2 = DescendedState;
|
||||
//cout << "Here 3a" << "\tipart2 " << ipart2 << "\tihole2 " << ihole2 << endl;
|
||||
//cout << DescendedState2.Ix2 << endl;
|
||||
DescendedState2.Annihilate_ph_pair(ipart2, ihole2, OriginIx2);
|
||||
DescendedState2.Compute_All(true);
|
||||
//cout << DescendedState2.Ix2 << endl;
|
||||
//cout << DescendedState2.lambdaoc << endl;
|
||||
|
||||
DP densityME_top_desc2 = real(exp(ln_Density_ME (TopState, DescendedState2)));
|
||||
DP densityME_desc2_ground = real(exp(ln_Density_ME (DescendedState2, GroundState)));
|
||||
|
||||
//contrib_estimate += Weight_integral[Weight_integral.size()/2 + (TopState.iK - DescendedState2.iK)]
|
||||
//* Weight_integral[Weight_integral.size()/2 + (DescendedState2.iK - GroundState.iK)]
|
||||
//* densityME_top_desc2 * densityME_desc2_ground
|
||||
///((GroundState.E - TopState.E) * (GroundState.E - DescendedState2.E));
|
||||
|
||||
// if intermediate state has momentum within allowable window, OK, otherwise discard contribution:
|
||||
if (abs(TopState.iK - DescendedState2.iK) < FT_of_potential.size()/2 &&
|
||||
abs(DescendedState2.iK - GroundState.iK) < FT_of_potential.size()/2) {
|
||||
|
@ -144,26 +113,19 @@ namespace ABACUS {
|
|||
for (int ihole3 = ihole2; ihole3 < nphpairs - 2; ++ihole3) {
|
||||
|
||||
LiebLin_Bethe_State DescendedState3 = DescendedState2;
|
||||
//cout << "Here 4a" << "\tipart3 " << ipart3 << "\tihole3 " << ihole3 << endl;
|
||||
DescendedState3.Annihilate_ph_pair(ipart3, ihole3, OriginIx2);
|
||||
//cout << DescendedState3.Ix2 << endl;
|
||||
DescendedState3.Compute_All(true);
|
||||
//cout << DescendedState3.Ix2 << endl;
|
||||
|
||||
DP densityME_top_desc3 = real(exp(ln_Density_ME (TopState, DescendedState3)));
|
||||
DP densityME_desc3_ground = real(exp(ln_Density_ME (DescendedState3, GroundState)));
|
||||
|
||||
//contrib_estimate += Weight_integral[Weight_integral.size()/2 + (TopState.iK - DescendedState3.iK)]
|
||||
//* Weight_integral[Weight_integral.size()/2 + (DescendedState3.iK - GroundState.iK)]
|
||||
//* densityME_top_desc3 * densityME_desc3_ground
|
||||
///((GroundState.E - TopState.E) * (GroundState.E - DescendedState3.E));
|
||||
|
||||
// if intermediate state has momentum within allowable window, OK, otherwise discard contribution:
|
||||
if (abs(TopState.iK - DescendedState3.iK) < FT_of_potential.size()/2 &&
|
||||
abs(DescendedState3.iK - GroundState.iK) < FT_of_potential.size()/2) {
|
||||
|
||||
contrib_estimate += abs(FT_of_potential[FT_of_potential.size()/2 + (TopState.iK - DescendedState3.iK)]
|
||||
* FT_of_potential[FT_of_potential.size()/2 + (DescendedState3.iK - GroundState.iK)]
|
||||
* FT_of_potential[FT_of_potential.size()/2
|
||||
+ (DescendedState3.iK - GroundState.iK)]
|
||||
* densityME_top_desc3 * densityME_desc3_ground
|
||||
/((GroundState.E - TopState.E) * (GroundState.E - DescendedState3.E)));
|
||||
|
||||
|
@ -181,34 +143,12 @@ namespace ABACUS {
|
|||
} // for ipart
|
||||
} // if nphpairs >= 2
|
||||
|
||||
//cout << "Here b" << endl;
|
||||
//cout << "type_id " << TopState.type_id << "\tid " << TopState.id << "\tcontrib_est = " << contrib_estimate << "\tnr_cont = " << nr_cont << endl;
|
||||
|
||||
return(contrib_estimate);
|
||||
}
|
||||
|
||||
/*
|
||||
DP Estimate_Contribution_of_Base_to_2nd_Order_PT (LiebLin_Bethe_State& ScanState, LiebLin_Bethe_State& GroundState,
|
||||
Vect_DP Weight_integral, LiebLin_States_and_Density_ME_of_Base& StatesBase)
|
||||
{
|
||||
// This function calculates the second-order perturbation theory contribution to
|
||||
// state ScanState coming from states of base defined in StatesBase.
|
||||
|
||||
DP sum_contrib = 0.0;
|
||||
|
||||
for (int i = 0; i <= StatesBase.maxid; ++i)
|
||||
sum_contrib += Weight_integral[Weight_integral.size()/2 + (ScanState.iK - StatesBase.State[i].iK)]
|
||||
* Weight_integral[Weight_integral.size()/2 + (StatesBase.State[i].iK - GroundState.iK)]
|
||||
* real(exp(ln_Density_ME (ScanState, StatesBase.State[i]))) * StatesBase.densityME[i]
|
||||
/((GroundState.E - StatesBase.State[i].E) * (GroundState.E - ScanState.E));
|
||||
// The strange vector size is so that iK == 0 corresponds to index size/2, as per convention
|
||||
return(sum_contrib);
|
||||
}
|
||||
*/
|
||||
|
||||
void Select_States_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required, bool symmetric_states, int iKmod,
|
||||
//int weighing_option, DP (*weight_integrand_fn) (Vect_DP), Vect_DP& args_to_weight_integrand)
|
||||
int weighing_option, Vect<complex <DP> >& FT_of_potential)
|
||||
void Select_States_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required,
|
||||
bool symmetric_states, int iKmod, int weighing_option, Vect<complex <DP> >& FT_of_potential)
|
||||
{
|
||||
// This function reads an existing partition function file and determines whether
|
||||
// each state is to be included in NRG by applying an energy, momentum and form factor criterion.
|
||||
|
@ -218,7 +158,6 @@ namespace ABACUS {
|
|||
// weighing_option == 1: ordering according to perturbation theory in single p-h annihilation path
|
||||
// weighing_option == 2: same as 1, but output of list is ordered in weight
|
||||
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, 'Z', c_int, L, N, iKmin, iKmax, 0.0, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
@ -250,21 +189,10 @@ namespace ABACUS {
|
|||
NRG_outfile.open(NRG_Cstr);
|
||||
if (NRG_outfile.fail()) ABACUSerror("Could not open NRG_outfile... ");
|
||||
|
||||
//NRG_outfile.setf(ios::scientific);
|
||||
NRG_outfile.precision(16);
|
||||
|
||||
|
||||
// Read the whole data file:
|
||||
/*
|
||||
// estimate its size:
|
||||
struct stat statbuf;
|
||||
stat (RAW_Cstr, &statbuf);
|
||||
int filesize = statbuf.st_size;
|
||||
// Determine the number of entries approximately
|
||||
int entry_size = 1* sizeof(double) + 2*sizeof(int) + 3* sizeof(long long int);
|
||||
|
||||
int estimate_nr_entries = filesize/entry_size;
|
||||
*/
|
||||
|
||||
// Count the number of entries in raw file:
|
||||
int estimate_nr_entries = 0;
|
||||
|
@ -273,13 +201,10 @@ namespace ABACUS {
|
|||
getline(infile, line);
|
||||
estimate_nr_entries++;
|
||||
}
|
||||
|
||||
const int MAXDATA = estimate_nr_entries;
|
||||
//cout << "estimate_nr_entries: " << estimate_nr_entries << endl;
|
||||
|
||||
DP* E = new DP[MAXDATA];
|
||||
int* iK = new int[MAXDATA];
|
||||
//int* conv = new int[MAXDATA];
|
||||
string* label = new string[MAXDATA];
|
||||
bool* sym = new bool[MAXDATA];
|
||||
|
||||
|
@ -291,12 +216,10 @@ namespace ABACUS {
|
|||
while (((infile.peek()) != EOF) && (Ndata < MAXDATA)) {
|
||||
infile >> E[Ndata];
|
||||
infile >> iK[Ndata];
|
||||
//infile >> conv[Ndata];
|
||||
infile >> label[Ndata];
|
||||
Ndata++;
|
||||
}
|
||||
|
||||
//cout << "input " << Ndata << " data lines." << endl;
|
||||
infile.close();
|
||||
|
||||
// Define the ground state:
|
||||
|
@ -313,30 +236,8 @@ namespace ABACUS {
|
|||
// To cover negative and positive momenta (in case potential is not symmetric),
|
||||
// we define the Weight_integral vector entry with index size/2 as corresponding to iK == 0.
|
||||
|
||||
/*
|
||||
// DEPRECATED 25/1/2012: from now on (ABACUS++T_8 onwards), use FT of potential as argument to this function.
|
||||
Vect_DP Weight_integral (0.0, 4* (iKmax - iKmin)); // we give a large window
|
||||
|
||||
//Vect_DP args(0.0, 2);
|
||||
DP req_rel_prec = 1.0e-6;
|
||||
DP req_abs_prec = 1.0e-6;
|
||||
int max_nr_pts = 10000;
|
||||
|
||||
for (int iK = -Weight_integral.size()/2; iK < Weight_integral.size()/2; ++iK) {
|
||||
|
||||
args_to_weight_integrand[1] = DP(iK);
|
||||
|
||||
Integral_result answer = Integrate_optimal (weight_integrand_fn, args_to_weight_integrand,
|
||||
0, 0.0, 0.5, req_rel_prec, req_abs_prec, max_nr_pts);
|
||||
|
||||
Weight_integral[Weight_integral.size()/2 + iK] = answer.integ_est;
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
// Calculate weight of states using selection criterion function
|
||||
|
||||
//DP absdensityME = 0.0;
|
||||
DP* weight = new DP[Ndata];
|
||||
|
||||
// For weighing using 2nd order PT, we only trace over 2 excitation states (1 p-h pair)
|
||||
|
@ -344,8 +245,6 @@ namespace ABACUS {
|
|||
|
||||
for (int i = 0; i < Ndata; ++i) {
|
||||
|
||||
//cout << i << " out of " << Ndata << "\tlabel = " << label[i] << endl;
|
||||
|
||||
if (abs(iK[i]) % iKmod != 0) { // if iK not a multiple of iKmod: give stupidly high weight.
|
||||
weight[i] = 1.0e+100;
|
||||
sym[i] = false; // doesn't matter
|
||||
|
@ -359,16 +258,11 @@ namespace ABACUS {
|
|||
if (weighing_option == 1 || weighing_option == 2) ScanState.Compute_All(true);
|
||||
sym[i] = ScanState.Check_Symmetry();
|
||||
|
||||
//cout << "Setting state " << i << "\t to label " << label[i] << "\tsym: " << sym[i] << endl;
|
||||
|
||||
// WEIGHING THE STATES: **********************************************
|
||||
|
||||
State_Label_Data currentdata = Read_State_Label (label[i], OriginIx2);
|
||||
if (currentdata.nexc[0] == 0) weight[i] = 0.0;
|
||||
|
||||
else if (symmetric_states && iK[i] < 0 || iK[i] < iKmin || iK[i] > iKmax) weight[i] = 1.0e+100;
|
||||
|
||||
//else if (symmetric_states && iK[i] == 0 && !ScanState.Check_Symmetry()) {
|
||||
else if (symmetric_states && iK[i] == 0 && !sym[i]) {
|
||||
// This state is at zero momentum but not symmetric. we keep it only if
|
||||
// the first non-symmetric pair of quantum numbers is right-weighted:
|
||||
|
@ -378,7 +272,6 @@ namespace ABACUS {
|
|||
if (weighing_option == 0) weight[i] = E[i];
|
||||
else if (weighing_option == 1 || weighing_option == 2)
|
||||
weight[i] = 1.0/(1.0e-100 + fabs(Estimate_Contribution_of_Single_ph_Annihilation_Path_to_2nd_Order_PT
|
||||
//(ScanState, GroundState, Weight_integral)));
|
||||
(ScanState, GroundState, FT_of_potential)));
|
||||
}
|
||||
else weight[i] = 1.0e+100;
|
||||
|
@ -388,10 +281,8 @@ namespace ABACUS {
|
|||
if (weighing_option == 0) weight[i] = E[i];
|
||||
else if (weighing_option == 1 || weighing_option == 2)
|
||||
weight[i] = 1.0/(1.0e-100 + fabs(Estimate_Contribution_of_Single_ph_Annihilation_Path_to_2nd_Order_PT
|
||||
//(ScanState, GroundState, Weight_integral)));
|
||||
(ScanState, GroundState, FT_of_potential)));
|
||||
}
|
||||
//cout << i << " out of " << Ndata << "\tlabel = " << label[i] << "\tweight = " << weight[i] << endl;
|
||||
}
|
||||
} // for i
|
||||
|
||||
|
@ -402,18 +293,15 @@ namespace ABACUS {
|
|||
|
||||
QuickSort(weight, index, 0, Ndata - 1);
|
||||
|
||||
|
||||
// Select states by increasing weight, with a max of Nstates_required entries
|
||||
|
||||
DP* E_kept = new DP[Nstates_required];
|
||||
int* iK_kept = new int[Nstates_required];
|
||||
//int* conv_kept = new int[Nstates_required];
|
||||
string* label_kept = new string[Nstates_required];
|
||||
bool* sym_kept = new bool[Nstates_required];
|
||||
DP* weight_kept = new DP[Nstates_required];
|
||||
|
||||
// Copy selected states into new vectors:
|
||||
|
||||
for (int i = 0; i < ABACUS::min(Ndata, Nstates_required); ++i) {
|
||||
E_kept[i] = E[index[i] ];
|
||||
iK_kept[i] = iK[index[i] ];
|
||||
|
@ -425,7 +313,6 @@ namespace ABACUS {
|
|||
|
||||
|
||||
// If needed, order selected states by increasing energy:
|
||||
|
||||
int* index_kept = new int[Nstates_required];
|
||||
for (int i = 0; i < Nstates_required; ++i) index_kept[i] = i;
|
||||
|
||||
|
@ -436,19 +323,16 @@ namespace ABACUS {
|
|||
for (int i = 0; i < Nstates_required; ++i) {
|
||||
if (i > 0) NRG_outfile << endl;
|
||||
NRG_outfile << i << "\t" << E_kept[i] << "\t" << iK_kept[index_kept[i] ]
|
||||
//<< "\t" << conv_kept[index_kept[i] ]
|
||||
<< "\t" << label_kept[index_kept[i] ]
|
||||
<< "\t" << sym_kept[index_kept[i] ] << "\t" << weight_kept[index_kept[i] ];
|
||||
}
|
||||
|
||||
delete[] E;
|
||||
delete[] iK;
|
||||
//delete[] conv;
|
||||
delete[] label;
|
||||
delete[] sym;
|
||||
delete[] E_kept;
|
||||
delete[] iK_kept;
|
||||
//delete[] conv_kept;
|
||||
delete[] label_kept;
|
||||
delete[] sym_kept;
|
||||
delete[] weight;
|
||||
|
@ -458,5 +342,4 @@ namespace ABACUS {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ABACUS
|
||||
|
|
|
@ -37,7 +37,8 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
ODSLF_Base::ODSLF_Base (const Heis_Chain& RefChain, int M)
|
||||
: Mdown(M), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings))
|
||||
: Mdown(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;
|
||||
|
@ -55,15 +56,14 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
ODSLF_Base::ODSLF_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities)
|
||||
: Mdown(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)),
|
||||
id (0LL)
|
||||
: Mdown(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 ODSLF_Base constructor.");
|
||||
if (RefChain.Nstrings != Nrapidities.size())
|
||||
ABACUSerror("Incompatible Nrapidities vector used in ODSLF_Base constructor.");
|
||||
|
||||
int Mcheck = 0;
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
|
||||
|
@ -81,14 +81,13 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
// Now compute the Ix2_infty numbers
|
||||
|
||||
(*this).Compute_Ix2_limits(RefChain);
|
||||
|
||||
}
|
||||
|
||||
ODSLF_Base::ODSLF_Base (const Heis_Chain& RefChain, long long int id_ref)
|
||||
: Mdown(0), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)),
|
||||
id (id_ref)
|
||||
: Mdown(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
|
||||
|
||||
|
@ -101,14 +100,6 @@ namespace ABACUS {
|
|||
}
|
||||
Nrap[0] = id_eff;
|
||||
|
||||
//id = id_ref;
|
||||
|
||||
//cout << "In ODSLF_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 ODSLFBase constructor.");
|
||||
|
||||
int Mcheck = 0;
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
|
||||
Mdown = Mcheck;
|
||||
|
@ -117,7 +108,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);
|
||||
}
|
||||
|
||||
|
@ -167,7 +157,8 @@ 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])
|
||||
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));
|
||||
|
@ -179,7 +170,8 @@ 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])
|
||||
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.
|
||||
|
@ -192,17 +184,12 @@ namespace ABACUS {
|
|||
|
||||
// Reject formally infinite rapidities (i.e. if Delta is root of unity)
|
||||
|
||||
//cout << "Ix2_infty - Ix2_max = " << Ix2_infty[j] - Ix2_max[j] << endl;
|
||||
//if (Ix2_infty[j] == Ix2_max[j]) {
|
||||
//Ix2_max[j] -= 2;
|
||||
//}
|
||||
|
||||
// If Nrap is even, Ix2_max must be odd. If odd, then even.
|
||||
//if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1; DEACTIVATED FOR ODSLF !
|
||||
|
||||
// For ODSLF: parity of quantum numbers is complicated:
|
||||
// if (N-1 + M_j + (M + 1) n_j + (1 - nu_j) N/2) is even, q# are integers, so Ix2_max must be even (conversely, if odd, then odd).
|
||||
if ((Ix2_max[j] + RefChain.Nsites - 1 + Nrap[j] + (Nraptot + 1) * RefChain.Str_L[j] + (RefChain.par[j] == 1 ? 0 : RefChain.Nsites)) % 2) Ix2_max[j] -= 1;
|
||||
// if (N-1 + M_j + (M + 1) n_j + (1 - nu_j) N/2) is even, q# are integers,
|
||||
// so Ix2_max must be even (conversely, if odd, then odd).
|
||||
if ((Ix2_max[j] + RefChain.Nsites - 1 + Nrap[j] + (Nraptot + 1) * RefChain.Str_L[j]
|
||||
+ (RefChain.par[j] == 1 ? 0 : RefChain.Nsites)) % 2) Ix2_max[j] -= 1;
|
||||
|
||||
while (Ix2_max[j] > RefChain.Nsites) {
|
||||
Ix2_max[j] -= 2;
|
||||
|
@ -225,7 +212,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.
|
||||
|
@ -292,16 +278,14 @@ 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
|
||||
|
||||
}
|
||||
|
||||
void ODSLF_Base::Scan_for_Possible_Types (Vect<long long int>& possible_type_id, int& nfound, int base_level, Vect<int>& Nexcitations)
|
||||
void ODSLF_Base::Scan_for_Possible_Types (Vect<long long int>& possible_type_id, int& nfound,
|
||||
int base_level, Vect<int>& Nexcitations)
|
||||
{
|
||||
if (base_level == 0) {
|
||||
// We set all sectors 0, 1, 2, 3
|
||||
|
@ -335,8 +319,7 @@ namespace ABACUS {
|
|||
// We scan over the possible distributions of the excitations on the L and R sides:
|
||||
|
||||
// Count the number of slots available on R:
|
||||
//int Nexc_R_max = Ix2_max[base_level]/2 + 1;
|
||||
int Nexc_R_max = (Ix2_max[base_level] + 2)/2; // bug in earlier line: if Ix2_max < 0, must have Nexc_R_max == 0, not 1.
|
||||
int Nexc_R_max = (Ix2_max[base_level] + 2)/2;
|
||||
int Nexc_L_max = (Ix2_max[base_level] + 1)/2;
|
||||
for (int Nexcleft = 0; Nexcleft <= Nrap[base_level]; ++Nexcleft)
|
||||
if (Nexcleft <= Nexc_L_max && Nrap[base_level] - Nexcleft <= Nexc_R_max) {
|
||||
|
@ -376,44 +359,22 @@ namespace ABACUS {
|
|||
|
||||
ODSLF_Ix2_Config::ODSLF_Ix2_Config (const Heis_Chain& RefChain, int M)
|
||||
: Nstrings(1), Nrap(Vect<int>(M,1)), Nraptot(M), Ix2(new int*[1]) // single type of string here
|
||||
//: Ix2 (Vect<Vect<int> > (1))
|
||||
{
|
||||
Ix2[0] = new int[M];
|
||||
//Ix2[0] = Vect<int> (M);
|
||||
|
||||
for (int j = 0; j < M; ++j) {
|
||||
Ix2[0][j] = -(M - 1) + 2*j;
|
||||
/*
|
||||
cout << j << "\t" << Ix2[0][j] << endl;
|
||||
cout << "Here 1" << endl;
|
||||
cout << RefChain.Str_L[0] << endl;
|
||||
// ODSLF: put back correct parity of quantum nr:
|
||||
cout << "M = " << M << endl;
|
||||
cout << Ix2[0][j] << endl;
|
||||
cout << Nrap[0] << endl;
|
||||
cout << Nraptot << endl;
|
||||
cout << RefChain.Str_L[0] << endl;
|
||||
cout << RefChain.par[0] << endl;
|
||||
cout << RefChain.Nsites << endl;
|
||||
if ((Ix2[0][j] + RefChain.Nsites - 1 + Nrap[0] + (Nraptot + 1) * RefChain.Str_L[0] + (RefChain.par[0] == 1 ? 0 : RefChain.Nsites)) % 2) Ix2[0][j] -= 1;
|
||||
cout << "Here 2" << endl;
|
||||
*/
|
||||
// Use simplification: Nrap[0] = M = Nraptot, Str_L[0] = 1, par = 1, so
|
||||
if ((Ix2[0][j] + RefChain.Nsites) % 2) Ix2[0][j] -= 1;
|
||||
//OBSOLETE: 1 - (M % 2); // last term: correction for ODSLF
|
||||
}
|
||||
}
|
||||
|
||||
ODSLF_Ix2_Config::ODSLF_Ix2_Config (const Heis_Chain& RefChain, const ODSLF_Base& base)
|
||||
: Nstrings(RefChain.Nstrings), Nrap(base.Nrap), Nraptot(base.Nraptot), Ix2(new int*[RefChain.Nstrings])
|
||||
//: Ix2 (Vect<Vect<int> > (RefChain.Nstrings))
|
||||
{
|
||||
//Ix2[0] = new int[base.Mdown];
|
||||
Ix2[0] = new int[base.Nraptot];
|
||||
for (int i = 1; i < RefChain.Nstrings; ++i) Ix2[i] = Ix2[i-1] + base[i-1];
|
||||
|
||||
//for (int i = 0; i < RefChain.Nstrings; ++i) Ix2[i] = Vect<int> (base[i]);
|
||||
|
||||
// And now for the other string types...
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) {
|
||||
for (int j = 0; j < base[i]; ++j) Ix2[i][j] = -(base[i] - 1) + 2*j + 1 - (base[i] % 2);
|
||||
|
@ -424,30 +385,11 @@ namespace ABACUS {
|
|||
for (int j = 0; j < base[i]; ++j)
|
||||
if ((Ix2[i][j] + RefChain.Nsites - 1 + base.Nrap[i] + (base.Nraptot + 1) * RefChain.Str_L[i] + (RefChain.par[i] == 1 ? 0 : RefChain.Nsites)) % 2)
|
||||
Ix2[i][j] -= 1;
|
||||
|
||||
/*
|
||||
// New meaning of negative parity:
|
||||
for (int j = 1; j < base.Nrap.size(); ++j)
|
||||
if (RefChain.par[j] == -1) // we `invert' the meaning of the quantum numbers
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
if (Ix2[j][alpha] >= 0) Ix2[j][alpha] -= 2*(base.Ix2_max[j]/2 + 1);
|
||||
else Ix2[j][alpha] += 2*(base.Ix2_max[j]/2 + 1);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
ODSLF_Ix2_Config& ODSLF_Ix2_Config::operator= (const ODSLF_Ix2_Config& RefConfig)
|
||||
{
|
||||
if (this != &RefConfig) {
|
||||
/*
|
||||
Ix2 = Vect<Vect<int> > (RefConfig.Ix2.size());
|
||||
for (int i = 0; i < RefConfig.Ix2.size(); ++i) {
|
||||
Ix2[i] = Vect<int> (RefConfig.Ix2[i].size());
|
||||
for (int j = 0; j < RefConfig.Ix2[i].size(); ++j)
|
||||
Ix2[i][j] = RefConfig.Ix2[i][j];
|
||||
}
|
||||
*/
|
||||
|
||||
Nstrings = RefConfig.Nstrings;
|
||||
Nrap = RefConfig.Nrap;
|
||||
Nraptot = RefConfig.Nraptot;
|
||||
|
@ -494,22 +436,17 @@ namespace ABACUS {
|
|||
|
||||
ODSLF_Lambda::ODSLF_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;
|
||||
}
|
||||
|
||||
ODSLF_Lambda::ODSLF_Lambda (const Heis_Chain& RefChain, const ODSLF_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;
|
||||
|
@ -519,15 +456,6 @@ namespace ABACUS {
|
|||
ODSLF_Lambda& ODSLF_Lambda::operator= (const ODSLF_Lambda& RefLambda)
|
||||
{
|
||||
if (this != &RefLambda) {
|
||||
//lambda = RefLambda.lambda;
|
||||
/*
|
||||
lambda = Vect<Vect<DP> > (RefLambda.lambda.size());
|
||||
for (int i = 0; i < RefLambda.lambda.size(); ++i) {
|
||||
lambda[i] = Vect<DP> (RefLambda.lambda[i].size());
|
||||
for (int j = 0; j < RefLambda.lambda[i].size(); ++j) lambda[i][j] = RefLambda.lambda[i][j];
|
||||
}
|
||||
*/
|
||||
|
||||
Nstrings = RefLambda.Nstrings;
|
||||
Nrap = RefLambda.Nrap;
|
||||
Nraptot = RefLambda.Nraptot;
|
||||
|
@ -586,15 +514,16 @@ namespace ABACUS {
|
|||
(*this) = ODSLF_Ix2_Offsets(RefBase, nparticles);
|
||||
}
|
||||
|
||||
ODSLF_Ix2_Offsets::ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, Vect<int> nparticles) // sets all tableaux to empty ones, with nparticles at each level
|
||||
: base(RefBase), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)), type_id(Ix2_Offsets_type_id (nparticles)), id(0LL), maxid(0LL)
|
||||
ODSLF_Ix2_Offsets::ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, Vect<int> nparticles)
|
||||
// sets all tableaux to empty ones, with nparticles at each level
|
||||
: base(RefBase), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)),
|
||||
type_id(Ix2_Offsets_type_id (nparticles)), id(0LL), maxid(0LL)
|
||||
{
|
||||
|
||||
// Checks on nparticles vector:
|
||||
|
||||
if (nparticles.size() != 2 * base.Nrap.size() + 2) ABACUSerror("Wrong nparticles.size in Ix2_Offsets constructor.");
|
||||
if (nparticles.size() != 2 * base.Nrap.size() + 2)
|
||||
ABACUSerror("Wrong nparticles.size in Ix2_Offsets constructor.");
|
||||
|
||||
//if (base.Nrap[0] != (nparticles[3] + nparticles[2] + base.Mdown - nparticles[0] - nparticles[1])) ABACUSerror("Wrong Nrap[0] in Ix2_Offsets constructor.");
|
||||
if (nparticles[3] + nparticles[2] != nparticles[0] + nparticles[1]) {
|
||||
cout << nparticles[0] << "\t" << nparticles[1] << "\t" << nparticles[2] << "\t" << nparticles[3] << endl;
|
||||
ABACUSerror("Wrong Npar[0-3] in Ix2_Offsets constructor.");
|
||||
|
@ -602,32 +531,39 @@ namespace ABACUS {
|
|||
|
||||
for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
|
||||
if (base.Nrap[base_level] != nparticles[2*base_level + 2] + nparticles[2*base_level + 3]) {
|
||||
cout << base_level << "\t" << base.Nrap[base_level] << "\t" << nparticles[2*base_level + 2] << "\t" << nparticles[2*base_level + 3] << endl;
|
||||
cout << base_level << "\t" << base.Nrap[base_level] << "\t" << nparticles[2*base_level + 2]
|
||||
<< "\t" << nparticles[2*base_level + 3] << endl;
|
||||
ABACUSerror("Wrong Nrap[] in Ix2_Offsets constructor.");
|
||||
}
|
||||
|
||||
// nparticles[0,1]: number of holes on R and L side in GS interval
|
||||
if (nparticles[0] > (base.Nrap[0] + 1)/2) ABACUSerror("nparticles[0] too large in Ix2_Offsets constructor.");
|
||||
if (nparticles[1] > base.Nrap[0]/2) ABACUSerror("nparticles[1] too large in Ix2_Offsets constructor.");
|
||||
if (nparticles[0] > (base.Nrap[0] + 1)/2)
|
||||
ABACUSerror("nparticles[0] too large in Ix2_Offsets constructor.");
|
||||
if (nparticles[1] > base.Nrap[0]/2)
|
||||
ABACUSerror("nparticles[1] too large in Ix2_Offsets constructor.");
|
||||
|
||||
// nparticles[2,3]: number of particles of type 0 on R and L side out of GS interval
|
||||
if (nparticles[2] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) ABACUSerror("nparticles[2] too large in Ix2_Offsets constructor.");
|
||||
if (nparticles[3] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) ABACUSerror("nparticles[3] too large in Ix2_Offsets constructor.");
|
||||
if (nparticles[2] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2)
|
||||
ABACUSerror("nparticles[2] too large in Ix2_Offsets constructor.");
|
||||
if (nparticles[3] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2)
|
||||
ABACUSerror("nparticles[3] too large in Ix2_Offsets constructor.");
|
||||
|
||||
for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
|
||||
//if ((nparticles[2*base_level + 2] > 0 && nparticles[2*base_level + 2] > (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
|
||||
if ((nparticles[2*base_level + 2] > 0 && nparticles[2*base_level + 2] > (base.Ix2_max[base_level] + 2)/2) // ODSLF modif
|
||||
//|| (nparticles[2*base_level + 3] > 0 && nparticles[2*base_level + 3] > (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2)) {
|
||||
if ((nparticles[2*base_level + 2] > 0 && nparticles[2*base_level + 2]
|
||||
> (base.Ix2_max[base_level] + 2)/2) // ODSLF modif
|
||||
|| (nparticles[2*base_level + 3] > 0
|
||||
//&& nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2))
|
||||
&& nparticles[2*base_level + 3] > (base.Ix2_max[base_level] + 1)/2)) // ODSLF modif
|
||||
{
|
||||
cout << base_level << "\t" << base.Ix2_max[base_level] << "\t" << base.Ix2_infty[base_level] << "\t" << nparticles[2*base_level + 2] << "\t" << (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2
|
||||
<< "\t" << nparticles[2*base_level + 3] << "\t" << (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2
|
||||
<< "\t" << (nparticles[2*base_level + 2] > 0) << "\t" << (nparticles[2*base_level + 2] > (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
|
||||
//<< "\t" << (nparticles[2*base_level + 3] > 0) << "\t" << (nparticles[2*base_level + 3] > (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2)
|
||||
cout << base_level << "\t" << base.Ix2_max[base_level] << "\t" << base.Ix2_infty[base_level]
|
||||
<< "\t" << nparticles[2*base_level + 2] << "\t"
|
||||
<< (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2
|
||||
<< "\t" << nparticles[2*base_level + 3] << "\t"
|
||||
<< (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2
|
||||
<< "\t" << (nparticles[2*base_level + 2] > 0) << "\t"
|
||||
<< (nparticles[2*base_level + 2] > (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
|
||||
<< "\t" << (nparticles[2*base_level + 3] > 0) << "\t"
|
||||
<< (nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
|
||||
<< (nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1
|
||||
- (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
|
||||
<< endl;
|
||||
ABACUSerror("nparticles too large in Ix2_Offsets constructor.");
|
||||
}
|
||||
|
@ -644,20 +580,19 @@ namespace ABACUS {
|
|||
|
||||
// Tableaux of index i = 2,...: data about string type i/2-1.
|
||||
for (int base_level = 1; base_level < base.Nrap.size(); ++base_level) {
|
||||
Tableau[2*base_level + 2] = Young_Tableau(nparticles[2*base_level + 2],
|
||||
//(base.Ix2_max[base_level] - ((base.Nrap[base_level]) % 2) + 2)/2 - nparticles[2*base_level + 2], Tableau[2]);
|
||||
//(base.Ix2_max[base_level] - base.Nrap[base_level] % 2 + 2)/2 - nparticles[2*base_level + 2], Tableau[2]);
|
||||
(base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2))/2 + 1 - nparticles[2*base_level + 2], Tableau[2]);
|
||||
Tableau[2*base_level + 3] = Young_Tableau(nparticles[2*base_level + 3],
|
||||
//(base.Ix2_max[base_level] - base.Nrap[base_level] % 2)/2 - nparticles[2*base_level + 3], Tableau[3]);
|
||||
(base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2 + 1 - nparticles[2*base_level + 3], Tableau[3]);
|
||||
Tableau[2*base_level + 2] =
|
||||
Young_Tableau(nparticles[2*base_level + 2],
|
||||
(base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2))/2 + 1
|
||||
- nparticles[2*base_level + 2], Tableau[2]);
|
||||
Tableau[2*base_level + 3] =
|
||||
Young_Tableau(nparticles[2*base_level + 3],
|
||||
(base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2 + 1
|
||||
- nparticles[2*base_level + 3], Tableau[3]);
|
||||
}
|
||||
|
||||
maxid = 1LL;
|
||||
//id = Tableau[0].id;
|
||||
for (int i = 0; i < nparticles.size(); ++i) {
|
||||
maxid *= Tableau[i].maxid + 1LL;
|
||||
//id += maxid + Tableau[i].id;
|
||||
}
|
||||
maxid -= 1LL;
|
||||
|
||||
|
@ -682,13 +617,14 @@ namespace ABACUS {
|
|||
|
||||
bool answer = true;
|
||||
for (int level = 0; level < 4; ++level) { // check fundamental level only
|
||||
//for (int level = 0; level < 2 * base.Nrap.size() + 2; ++level) {
|
||||
// First check whether all rows which exist in both tableaux satisfy rule:
|
||||
for (int tableau_level = 0; tableau_level < ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
|
||||
for (int tableau_level = 0; tableau_level
|
||||
< ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
|
||||
if (Tableau[level].Row_L[tableau_level] > RefOffsets.Tableau[level].Row_L[tableau_level])
|
||||
answer = false;
|
||||
// Now check whether there exist extra rows violating rule:
|
||||
for (int tableau_level = ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); tableau_level < Tableau[level].Nrows; ++tableau_level)
|
||||
for (int tableau_level = ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows);
|
||||
tableau_level < Tableau[level].Nrows; ++tableau_level)
|
||||
if (Tableau[level].Row_L[tableau_level] > 0) answer = false;
|
||||
}
|
||||
|
||||
|
@ -702,13 +638,14 @@ namespace ABACUS {
|
|||
|
||||
bool answer = true;
|
||||
for (int level = 0; level < 4; ++level) { // check fundamental level only
|
||||
//for (int level = 0; level < 2 * base.Nrap.size() + 2; ++level) {
|
||||
// First check whether all rows which exist in both tableaux satisfy rule:
|
||||
for (int tableau_level = 0; tableau_level < ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
|
||||
for (int tableau_level = 0; tableau_level
|
||||
< ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
|
||||
if (Tableau[level].Row_L[tableau_level] < RefOffsets.Tableau[level].Row_L[tableau_level])
|
||||
answer = false;
|
||||
// Now check whether there exist extra rows violating rule:
|
||||
for (int tableau_level = ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); tableau_level < RefOffsets.Tableau[level].Nrows; ++tableau_level)
|
||||
for (int tableau_level = ABACUS::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows);
|
||||
tableau_level < RefOffsets.Tableau[level].Nrows; ++tableau_level)
|
||||
if (RefOffsets.Tableau[level].Row_L[tableau_level] > 0) answer = false;
|
||||
}
|
||||
|
||||
|
@ -721,8 +658,6 @@ namespace ABACUS {
|
|||
// sub_id[0] + (total number of tableaux of type 0) * (sub_id[1] + (total number of tableaux of type 1) * (sub_id[2] + ...
|
||||
// + total number of tableaux of type (2*base.Nrap.size()) * sub_id[2*base.Nrap.size() + 1]
|
||||
|
||||
//cout << "Called Ix2_Offsets::Set_to_id" << endl;
|
||||
|
||||
if (idnr > maxid) {
|
||||
cout << idnr << "\t" << maxid << endl;
|
||||
ABACUSerror("idnr too large in offsets.Set_to_id.");
|
||||
|
@ -738,7 +673,6 @@ namespace ABACUS {
|
|||
Vect<long long int> result_choose(2*base.Nrap.size() + 2);
|
||||
|
||||
for (int i = 0; i <= 2*base.Nrap.size(); ++i) {
|
||||
//result_choose[i] = choose_lli(Tableau[i].Nrows + Tableau[i].Ncols, Tableau[i].Nrows);
|
||||
result_choose[i] = Tableau[i].maxid + 1LL;
|
||||
temp_prod *= result_choose[i];
|
||||
}
|
||||
|
@ -751,8 +685,8 @@ namespace ABACUS {
|
|||
sub_id[0] = idnr_eff; // what's left goes to the bottom...
|
||||
|
||||
for (int i = 0; i <= 2*base.Nrap.size() + 1; ++i) {
|
||||
//cout << "level = " << i << " Tableau.id = " << sub_id[i] << endl;
|
||||
if ((Tableau[i].Nrows * Tableau[i].Ncols == 0) && (sub_id[i] != 0)) ABACUSerror("index too large in offset.Set_to_id.");
|
||||
if ((Tableau[i].Nrows * Tableau[i].Ncols == 0) && (sub_id[i] != 0))
|
||||
ABACUSerror("index too large in offset.Set_to_id.");
|
||||
if (Tableau[i].id != sub_id[i]) Tableau[i].Set_to_id(sub_id[i]);
|
||||
}
|
||||
|
||||
|
@ -795,16 +729,11 @@ namespace ABACUS {
|
|||
if (Nboxes < 0) ABACUSerror("Can't use Nboxes < 0 in Add_Boxes_From_Lowest");
|
||||
else if (Nboxes == 0) return(true); // nothing to do
|
||||
|
||||
//cout << "Requesting Nboxes " << Nboxes << " in " << odd_sectors << " sectors." << endl;
|
||||
|
||||
int Nboxes_put = 0;
|
||||
int working_sector = odd_sectors;
|
||||
// We start from the bottom up.
|
||||
while (Nboxes_put < Nboxes && working_sector < 2*base.Nrap.size() + 2) {
|
||||
//cout << "working sector " << working_sector << "\tNboxes_put " << Nboxes_put << endl;
|
||||
//cout << "Tableau before put: " << Tableau[working_sector] << endl;
|
||||
Nboxes_put += Tableau[working_sector].Add_Boxes_From_Lowest(Nboxes - Nboxes_put);
|
||||
//cout << "Tableau after put: " << Tableau[working_sector] << endl;
|
||||
working_sector += 2;
|
||||
}
|
||||
Compute_id();
|
||||
|
@ -872,33 +801,21 @@ namespace ABACUS {
|
|||
};
|
||||
|
||||
ODSLF_Bethe_State::ODSLF_Bethe_State (const ODSLF_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(ODSLF_Ix2_Config(RefState.chain, RefState.base)),
|
||||
: chain(RefState.chain), base(RefState.base), offsets(RefState.offsets),
|
||||
Ix2(ODSLF_Ix2_Config(RefState.chain, RefState.base)),
|
||||
lambda(ODSLF_Lambda(RefState.chain, RefState.base)), BE(ODSLF_Lambda(RefState.chain, RefState.base)),
|
||||
diffsq(RefState.diffsq), conv(RefState.conv), iter(RefState.iter), iter_Newton(RefState.iter_Newton),
|
||||
E(RefState.E), iK(RefState.iK), K(RefState.K), lnnorm(RefState.lnnorm),
|
||||
//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)
|
||||
{
|
||||
// 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];
|
||||
lambda[j][alpha] = RefState.lambda[j][alpha];
|
||||
}
|
||||
}
|
||||
//cout << "Heis constructor state OK" << endl;
|
||||
}
|
||||
|
||||
ODSLF_Bethe_State::ODSLF_Bethe_State (const ODSLF_Bethe_State& RefState, long long int type_id_ref)
|
||||
|
@ -906,72 +823,49 @@ namespace ABACUS {
|
|||
Ix2(ODSLF_Ix2_Config(RefState.chain, RefState.base)), lambda(ODSLF_Lambda(RefState.chain, RefState.base)),
|
||||
BE(ODSLF_Lambda(RefState.chain, RefState.base)), diffsq(1.0), conv(0), iter(0), iter_Newton(0),
|
||||
E(0.0), iK(0), K(0.0), lnnorm(-100.0),
|
||||
//id(0LL), maxid(0LL)
|
||||
base_id(RefState.base_id), type_id(0LL), id(0LL), maxid(offsets.maxid), nparticles(0)
|
||||
{
|
||||
//cout << "Here in Heis constructor state type_id" << endl;
|
||||
//cout << "lambda " << lambda[0][0] << endl;
|
||||
//cout << "lambda OK" << endl;
|
||||
|
||||
(*this).Set_Ix2_Offsets (offsets);
|
||||
}
|
||||
|
||||
ODSLF_Bethe_State::ODSLF_Bethe_State (const Heis_Chain& RefChain, int M)
|
||||
: chain(RefChain), base(RefChain, M), offsets(base, 0LL), Ix2(ODSLF_Ix2_Config(RefChain, M)), lambda(ODSLF_Lambda(RefChain, M)),
|
||||
: chain(RefChain), base(RefChain, M), offsets(base, 0LL), Ix2(ODSLF_Ix2_Config(RefChain, M)),
|
||||
lambda(ODSLF_Lambda(RefChain, M)),
|
||||
BE(ODSLF_Lambda(RefChain, M)), diffsq(1.0), conv(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)
|
||||
{
|
||||
//cout << "Here in Heis constructor chain M" << endl;
|
||||
//cout << "requested M = " << M << endl;
|
||||
//cout << "lambda " << lambda[0][0] << endl;
|
||||
//cout << "lambda OK" << endl;
|
||||
}
|
||||
|
||||
ODSLF_Bethe_State::ODSLF_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& RefBase)
|
||||
: chain(RefChain), base(RefBase), offsets(RefBase, 0LL), Ix2(ODSLF_Ix2_Config(RefChain, RefBase)), lambda(ODSLF_Lambda(RefChain, RefBase)),
|
||||
BE(ODSLF_Lambda(RefChain, RefBase)), diffsq(1.0), conv(0), iter(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0),
|
||||
//id(0LL), maxid(0LL)
|
||||
: chain(RefChain), base(RefBase), offsets(RefBase, 0LL),
|
||||
Ix2(ODSLF_Ix2_Config(RefChain, RefBase)), lambda(ODSLF_Lambda(RefChain, RefBase)),
|
||||
BE(ODSLF_Lambda(RefChain, RefBase)), diffsq(1.0), conv(0), iter(0), iter_Newton(0),
|
||||
E(0.0), iK(0), K(0.0), lnnorm(-100.0),
|
||||
base_id(RefBase.id), type_id(0LL), id(0LL), maxid(offsets.maxid), nparticles(0)
|
||||
{
|
||||
// Check that the number of rapidities is consistent with Mdown
|
||||
|
||||
//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 ODSLF_Bethe_State constructor.");
|
||||
if (RefBase.Mdown != Mcheck)
|
||||
ABACUSerror("Wrong M from Nrapidities input vector, in ODSLF_Bethe_State constructor.");
|
||||
|
||||
}
|
||||
|
||||
ODSLF_Bethe_State::ODSLF_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
|
||||
: chain(RefChain), base(ODSLF_Base(RefChain, base_id_ref)), offsets(base, type_id_ref), Ix2(ODSLF_Ix2_Config(RefChain, base)), lambda(ODSLF_Lambda(RefChain, base)),
|
||||
BE(ODSLF_Lambda(RefChain, base)), diffsq(1.0), conv(0), iter(0), iter_Newton(0), E(0.0), iK(0), K(0.0), lnnorm(-100.0),
|
||||
//id(0LL), maxid(0LL)
|
||||
ODSLF_Bethe_State::ODSLF_Bethe_State (const Heis_Chain& RefChain,
|
||||
long long int base_id_ref, long long int type_id_ref)
|
||||
: chain(RefChain), base(ODSLF_Base(RefChain, base_id_ref)), offsets(base, type_id_ref),
|
||||
Ix2(ODSLF_Ix2_Config(RefChain, base)), lambda(ODSLF_Lambda(RefChain, base)),
|
||||
BE(ODSLF_Lambda(RefChain, base)), diffsq(1.0), conv(0), iter(0), iter_Newton(0),
|
||||
E(0.0), iK(0), K(0.0), lnnorm(-100.0),
|
||||
base_id(base_id_ref), type_id(type_id_ref), id(0LL), maxid(offsets.maxid), nparticles(0)
|
||||
{
|
||||
//cout << "Here in Heis constructor chain base_id type_id" << endl;
|
||||
//cout << "lambda " << lambda[0][0] << endl;
|
||||
//cout << "lambda OK" << endl;
|
||||
}
|
||||
|
||||
void ODSLF_Bethe_State::Set_Ix2_Offsets (const ODSLF_Ix2_Offsets& RefOffset) // sets the Ix2 to given offsets
|
||||
{
|
||||
if (base != RefOffset.base) ABACUSerror("Offset with incompatible base used in ODSLF_Bethe_State::Set_Ix2_Offsets.");
|
||||
/*
|
||||
// Check if total number of holes agrees with number of rapidities in higher particles
|
||||
int total_nr_holes = RefOffset.Tableau[0].Nrows + RefOffset.Tableau[1].Nrows;
|
||||
int total_nr_rap_in_particles = 0;
|
||||
for (int offsets_level = 2; offsets_level < RefOffset.Tableau.size(); offsets_level += 2)
|
||||
total_nr_rap_in_particles += chain.Str_L[offsets_level/2 - 1] * (RefOffset.Tableau[offsets_level].Nrows + RefOffset.Tableau[offsets_level + 1].Nrows);
|
||||
|
||||
cout << total_nr_holes << "\t" << total_nr_rap_in_particles << endl;
|
||||
|
||||
if (total_nr_holes != total_nr_rap_in_particles) ABACUSerror("Offset with incompatible Nparticles used in ODSLF_Bethe_State::Set_Ix2_Offsets.");
|
||||
*/
|
||||
if (base != RefOffset.base)
|
||||
ABACUSerror("Offset with incompatible base used in ODSLF_Bethe_State::Set_Ix2_Offsets.");
|
||||
|
||||
// For each base_level, we make sure that the Ix2 are ordered: Ix2[0][j] < Ix2[0][k] if j < k.
|
||||
|
||||
|
@ -979,103 +873,70 @@ namespace ABACUS {
|
|||
for (int j = 0; j < RefOffset.Tableau[2].Nrows; ++j) {
|
||||
Ix2[0][base.Nrap[0] - 1 - j]
|
||||
= base.Nrap[0] - 1 + 2* RefOffset.Tableau[2].Nrows - 2*j + 2*RefOffset.Tableau[2].Row_L[j];
|
||||
//cout << "R pcles, j = " << base.Nrap[0] - 1 - j << " Ix2[j] = " << Ix2[0][base.Nrap[0] - 1 - j] << endl;
|
||||
//cout << "j = " << j << "\tbase.Nrap[0] " << base.Nrap[0] << "\t2*RefOffset.Tableau[2].Nrows " << 2*RefOffset.Tableau[2].Nrows << "\t2*RefOffset.Tableau[2].Row_L[j] " << 2*RefOffset.Tableau[2].Row_L[j] << endl;
|
||||
//cout << base.Nrap[0] - 1 - j << "\t" << base.Nrap[0] - 1 + 2* RefOffset.Tableau[2].Nrows - 2*j + 2*RefOffset.Tableau[2].Row_L[j] << "\t" << Ix2[0][base.Nrap[0] - 1 - j] << "\t" << Ix2[0][9] << endl;
|
||||
}
|
||||
nparticles = RefOffset.Tableau[2].Nrows;
|
||||
//cout << "Here a" << endl;
|
||||
|
||||
// Level 0: holes in R part of GS interval
|
||||
for (int j = 0; j < RefOffset.Tableau[0].Ncols; ++j) {
|
||||
//Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[2].Nrows - j] = base.Nrap[0] - 1 - 2*RefOffset.Tableau[0].Nrows - 2*j + 2*RefOffset.Tableau[0].Col_L[j];
|
||||
Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[2].Nrows - j] = (base.Nrap[0] + 1) % 2 + 2*RefOffset.Tableau[0].Ncols - 2 - 2*j + 2*RefOffset.Tableau[0].Col_L[j];
|
||||
//cout << "R holes, j = " << base.Nrap[0] - 1 - RefOffset.Tableau[2].Nrows - j << " Ix2[j] = " << Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[2].Nrows - j] << endl;
|
||||
//cout << base.Nrap[0] << "\t" << (base.Nrap[0] + 1) % 2 << "\t" << RefOffset.Tableau[0].Ncols << "\t" << RefOffset.Tableau[0].Col_L[j] << endl;
|
||||
Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[2].Nrows - j] = (base.Nrap[0] + 1) % 2
|
||||
+ 2*RefOffset.Tableau[0].Ncols - 2 - 2*j + 2*RefOffset.Tableau[0].Col_L[j];
|
||||
}
|
||||
nparticles += RefOffset.Tableau[0].Ncols;
|
||||
|
||||
//cout << "Here b" << endl;
|
||||
|
||||
// Level 1: holes in L part of GS interval
|
||||
for (int j = 0; j < RefOffset.Tableau[1].Ncols; ++j) {
|
||||
Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[0].Ncols - RefOffset.Tableau[2].Nrows - j]
|
||||
= -1 - (base.Nrap[0] % 2) - 2* j - 2*RefOffset.Tableau[1].Col_L[RefOffset.Tableau[1].Ncols - 1 - j];
|
||||
//cout << "L holes, j = " << base.Nrap[0] - 1 - RefOffset.Tableau[0].Ncols - RefOffset.Tableau[2].Nrows- j << " Ix2[j] = " << Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[0].Ncols - RefOffset.Tableau[2].Nrows- j] << endl;
|
||||
}
|
||||
nparticles += RefOffset.Tableau[1].Ncols;
|
||||
|
||||
// cout << "Here c" << endl;
|
||||
|
||||
// Level 3: particles in L part outside GS interval
|
||||
for (int j = 0; j < RefOffset.Tableau[3].Nrows; ++j) {
|
||||
Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[0].Ncols - RefOffset.Tableau[1].Ncols - RefOffset.Tableau[2].Nrows - j]
|
||||
= -(base.Nrap[0] + 1 + 2*j + 2*RefOffset.Tableau[3].Row_L[RefOffset.Tableau[3].Nrows - 1 - j]);
|
||||
//cout << "R pcles, j = " << base.Nrap[0] - 1 - RefOffset.Tableau[0].Ncols - RefOffset.Tableau[1].Ncols - RefOffset.Tableau[2].Nrows << " Ix2[j] = " << Ix2[0][base.Nrap[0] - 1 - RefOffset.Tableau[0].Ncols - RefOffset.Tableau[1].Ncols - RefOffset.Tableau[2].Nrows] << endl;
|
||||
}
|
||||
nparticles += RefOffset.Tableau[3].Nrows;
|
||||
|
||||
//cout << "Here d" << endl;
|
||||
|
||||
// Subsequent levels: particles on R and L
|
||||
for (int base_level = 1; base_level < base.Nrap.size(); ++base_level) {
|
||||
|
||||
for (int j = 0; j < RefOffset.Tableau[2*base_level + 2].Nrows; ++j)
|
||||
Ix2[base_level][base.Nrap[base_level] - 1 - j]
|
||||
= ((base.Nrap[base_level] + 1) % 2) + 2*(RefOffset.Tableau[2*base_level + 2].Nrows - 1) -2*j + 2*RefOffset.Tableau[2*base_level + 2].Row_L[j];
|
||||
= ((base.Nrap[base_level] + 1) % 2) + 2*(RefOffset.Tableau[2*base_level + 2].Nrows - 1) -2*j
|
||||
+ 2*RefOffset.Tableau[2*base_level + 2].Row_L[j];
|
||||
|
||||
nparticles += RefOffset.Tableau[2*base_level + 2].Nrows;
|
||||
|
||||
for (int j = 0; j < RefOffset.Tableau[2*base_level + 3].Nrows; ++j)
|
||||
Ix2[base_level][base.Nrap[base_level] - 1 - RefOffset.Tableau[2*base_level + 2].Nrows - j]
|
||||
= -1 - ((base.Nrap[base_level]) % 2) -2*j - 2*RefOffset.Tableau[2*base_level + 3].Row_L[RefOffset.Tableau[2*base_level + 3].Nrows - 1 - j];
|
||||
= -1 - ((base.Nrap[base_level]) % 2) -2*j
|
||||
- 2*RefOffset.Tableau[2*base_level + 3].Row_L[RefOffset.Tableau[2*base_level + 3].Nrows - 1 - j];
|
||||
|
||||
nparticles += RefOffset.Tableau[2*base_level + 3].Nrows;
|
||||
}
|
||||
|
||||
//// Set the correct parity: quantum numbers always integer. Comparing ODSLF with Heis: if M is even, shift all Ix2 by +1:
|
||||
//if (base.Nrap[0] % 2 == 0)
|
||||
//for (int j = 0; j < base.Nrap[0]; ++j) Ix2[0][j] += 1; WRONG!!
|
||||
|
||||
// ODSLF: put back correct parity of quantum nr:
|
||||
for (int j = 0; j < base.Nrap.size(); ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha)
|
||||
if ((Ix2[j][alpha] + chain.Nsites - 1 + base.Nrap[j] + (base.Nraptot + 1) * chain.Str_L[j] + (chain.par[j] == 1 ? 0 : chain.Nsites)) % 2)
|
||||
if ((Ix2[j][alpha] + chain.Nsites - 1 + base.Nrap[j] + (base.Nraptot + 1) * chain.Str_L[j]
|
||||
+ (chain.par[j] == 1 ? 0 : chain.Nsites)) % 2)
|
||||
Ix2[j][alpha] -= 1;
|
||||
//cout << "Here e" << endl;
|
||||
|
||||
//id = RefOffset.id;
|
||||
//maxid = RefOffset.maxid;
|
||||
type_id = RefOffset.type_id;
|
||||
id = RefOffset.id;
|
||||
maxid = RefOffset.maxid;
|
||||
|
||||
/*
|
||||
// New meaning of negative parity:
|
||||
for (int j = 1; j < base.Nrap.size(); ++j)
|
||||
if (chain.par[j] == -1) // we `invert' the meaning of the quantum numbers
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
if (Ix2[j][alpha] >= 0) Ix2[j][alpha] -= 2*(base.Ix2_max[j]/2 + 1);
|
||||
else Ix2[j][alpha] += 2*(base.Ix2_max[j]/2 + 1);
|
||||
}
|
||||
*/
|
||||
|
||||
//cout << "After setting Ix2 with offsets of type_id " << type_id << " and id " << id << endl;
|
||||
//cout << RefOffset.Tableau[0].Nrows << "\t" << RefOffset.Tableau[0].Ncols << "\t" << RefOffset.Tableau[1].Nrows << "\t" << RefOffset.Tableau[1].Ncols << "\t" << RefOffset.Tableau[2].Nrows << "\t" << RefOffset.Tableau[2].Ncols << "\t" << RefOffset.Tableau[3].Nrows << "\t" << RefOffset.Tableau[3].Ncols << "\t" << endl;
|
||||
//cout << Ix2[0] << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
void ODSLF_Bethe_State::Set_to_id (long long int id_ref)
|
||||
{
|
||||
//cout << "Heis: Set_to_id called." << endl;
|
||||
offsets.Set_to_id (id_ref);
|
||||
(*this).Set_Ix2_Offsets (offsets);
|
||||
}
|
||||
|
||||
void ODSLF_Bethe_State::Set_to_id (long long int id_ref, ODSLF_Bethe_State& RefState)
|
||||
{
|
||||
//cout << "Heis: Set_to_id called." << endl;
|
||||
offsets.Set_to_id (id_ref);
|
||||
(*this).Set_Ix2_Offsets (offsets);
|
||||
}
|
||||
|
@ -1083,40 +944,20 @@ namespace ABACUS {
|
|||
bool ODSLF_Bethe_State::Check_Symmetry ()
|
||||
{
|
||||
// Checks whether the I's are symmetrically distributed.
|
||||
|
||||
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.
|
||||
// since Ix2 = N is same as Ix2 = -N by periodicity, this is symmetric.
|
||||
arg = (Ix2[j][alpha] != chain.Nsites) ? Ix2[j][alpha] : 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return symmetric_state;
|
||||
}
|
||||
|
@ -1141,15 +982,11 @@ namespace ABACUS {
|
|||
|
||||
void ODSLF_Bethe_State::Iterate_BAE ()
|
||||
{
|
||||
//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);
|
||||
//cout << j << "\t" << alpha << "\t" << Ix2[j][alpha] << "\t" << lambda_old << "\t" << lambda[j][alpha] << "\t";
|
||||
}
|
||||
//cout << endl;
|
||||
}
|
||||
|
||||
iter++;
|
||||
|
@ -1193,7 +1030,8 @@ namespace ABACUS {
|
|||
Vect_INT indx (base.Nraptot);
|
||||
|
||||
ODSLF_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);
|
||||
|
||||
|
@ -1216,16 +1054,13 @@ 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;
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
|
@ -1234,7 +1069,6 @@ namespace ABACUS {
|
|||
(*this).Compute_diffsq();
|
||||
|
||||
// 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]));
|
||||
|
@ -1258,7 +1092,6 @@ namespace ABACUS {
|
|||
prec_obtained = pow(BE[j][alpha], 2.0)/chain.Nsites;
|
||||
niter_here++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ODSLF_Bethe_State::Find_Rapidities (bool reset_rapidities)
|
||||
|
@ -1291,9 +1124,6 @@ namespace ABACUS {
|
|||
|
||||
while (diffsq > chain.prec && iter < 300 && iter_Newton < 20) {
|
||||
|
||||
// If we haven't reset, first try a few Newton steps...
|
||||
//if (!reset_rapidities && iter_Newton == 0) (*this).Solve_BAE_Newton (chain.prec, 10);
|
||||
|
||||
do {
|
||||
interp_start = clock();
|
||||
iter_interp_start = iter;
|
||||
|
@ -1307,18 +1137,13 @@ namespace ABACUS {
|
|||
|
||||
iter_prec = diffsq * 0.001;
|
||||
|
||||
//cout << "Interp: iter " << iter << "\tdiffsq " << diffsq << endl;
|
||||
|
||||
} while (diffsq > chain.prec && !is_nan(diffsq) && diffsq_interp_stop/diffsq_interp_start < 0.001);
|
||||
|
||||
// If we haven't even reached iter_prec, try normal iterations without extrapolations
|
||||
|
||||
if (diffsq > iter_prec) {
|
||||
(*this).Solve_BAE_smackdown (0.1 * diffsq, 1);
|
||||
}
|
||||
|
||||
//cout << "Smackdown: iter " << iter << "\tdiffsq " << diffsq << endl;
|
||||
|
||||
// Now try Newton
|
||||
|
||||
Newton_start = clock();
|
||||
|
@ -1331,14 +1156,10 @@ namespace ABACUS {
|
|||
iter_Newton_stop = iter_Newton;
|
||||
diffsq_Newton_stop = diffsq;
|
||||
|
||||
//cout << "Newton: iter " << iter_Newton << "\tdiffsq " << diffsq << endl;
|
||||
|
||||
if (diffsq > iter_prec) (*this).Solve_BAE_smackdown (0.1 * diffsq, 1);
|
||||
|
||||
if (diffsq > iter_prec) (*this).Solve_BAE_straight_iter (0.1 * diffsq, 50);
|
||||
|
||||
//cout << "Straight iter: iter " << iter << "\tdiffsq " << diffsq << endl;
|
||||
|
||||
// If we haven't converged here, retry with more precision in interp method...
|
||||
|
||||
if (is_nan(diffsq)) {
|
||||
|
@ -1352,9 +1173,6 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
// Check convergence:
|
||||
|
||||
//cout << "Check_Rapidities: " << (*this).Check_Rapidities() << endl;
|
||||
|
||||
conv = (diffsq < chain.prec && (*this).Check_Rapidities()) ? 1 : 0;
|
||||
|
||||
return;
|
||||
|
@ -1369,7 +1187,8 @@ namespace ABACUS {
|
|||
ODSLF_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...
|
||||
|
@ -1384,7 +1203,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];
|
||||
diffsq = diffsq_ref;
|
||||
}
|
||||
|
||||
|
@ -1400,7 +1220,8 @@ namespace ABACUS {
|
|||
ODSLF_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...
|
||||
|
@ -1415,7 +1236,8 @@ namespace ABACUS {
|
|||
|
||||
if ((diffsq > diffsq_ref)) {
|
||||
// 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];
|
||||
diffsq = diffsq_ref;
|
||||
}
|
||||
}
|
||||
|
@ -1429,7 +1251,8 @@ namespace ABACUS {
|
|||
ODSLF_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...
|
||||
|
@ -1446,15 +1269,17 @@ namespace ABACUS {
|
|||
while ((diffsq > interp_prec) && (max_iter_interp > iter_done_here)) {
|
||||
|
||||
(*this).Iterate_BAE();
|
||||
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];
|
||||
(*this).Iterate_BAE();
|
||||
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];
|
||||
(*this).Iterate_BAE();
|
||||
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];
|
||||
(*this).Iterate_BAE();
|
||||
for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda4[j][alpha] = lambda[j][alpha];
|
||||
//(*this).Iterate_BAE();
|
||||
//for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) lambda5[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];
|
||||
|
||||
iter_done_here += 4;
|
||||
|
||||
|
@ -1471,11 +1296,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;
|
||||
}
|
||||
|
||||
(*this).Iterate_BAE();
|
||||
|
@ -1483,7 +1305,8 @@ namespace ABACUS {
|
|||
|
||||
if ((diffsq >= diffsq_ref)) {
|
||||
// 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];
|
||||
diffsq = diffsq_ref;
|
||||
}
|
||||
|
||||
|
@ -1498,19 +1321,7 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -1577,15 +1388,19 @@ namespace ABACUS {
|
|||
{
|
||||
// sends all the state data to output stream
|
||||
|
||||
s << endl << "******** Chain with Nsites = " << state.chain.Nsites << " Mdown (nr fermions) = " << state.base.Mdown
|
||||
s << endl << "******** Chain with Nsites = " << state.chain.Nsites
|
||||
<< " Mdown (nr fermions) = " << state.base.Mdown
|
||||
<< ": eigenstate with base_id " << state.base_id << ", type_id " << state.type_id
|
||||
<< " id " << state.id << " maxid " << state.offsets.maxid << endl
|
||||
<< "E = " << state.E << " K = " << state.K << " iK = " << state.iK << " lnnorm = " << state.lnnorm << endl
|
||||
<< "conv = " << state.conv << " iter = " << state.iter << " iter_Newton = " << state.iter_Newton << "\tdiffsq " << state.diffsq << endl;
|
||||
<< "E = " << state.E << " K = " << state.K << " iK = " << state.iK
|
||||
<< " lnnorm = " << state.lnnorm << endl
|
||||
<< "conv = " << state.conv << " 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]
|
||||
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_max = " << state.base.Ix2_max[j] << endl;
|
||||
Vect_INT qnumbers(state.base.Nrap[j]);
|
||||
Vect_DP rapidities(state.base.Nrap[j]);
|
||||
|
@ -1610,6 +1425,4 @@ namespace ABACUS {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace ABACUS
|
||||
|
|
|
@ -16,125 +16,6 @@ Purpose: calculates the chemical potential.
|
|||
|
||||
namespace ABACUS {
|
||||
|
||||
/*
|
||||
DP Ezero (DP Delta, int N, int M)
|
||||
{
|
||||
// Returns the energy of the ground state with M down spins
|
||||
|
||||
if (M < 0 || M > N/2) ABACUSerror("M out of bounds in Ezero.");
|
||||
|
||||
DP E = -1.0; // sentinel value
|
||||
|
||||
if (M == 0) E = N * Delta/4.0;
|
||||
|
||||
else {
|
||||
|
||||
Heis_Chain BD1(1.0, Delta, 0.0, N);
|
||||
|
||||
Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
|
||||
|
||||
Nrapidities_groundstate[0] = M;
|
||||
|
||||
ODSLF_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
|
||||
|
||||
if ((Delta > 0.0) && (Delta < 1.0)) {
|
||||
ODSLF_XXZ_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else if (Delta == 1.0) {
|
||||
XXX_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else if (Delta > 1.0) {
|
||||
XXZ_gpd_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else ABACUSerror("Anisotropy out of bounds in Ezero.");
|
||||
}
|
||||
|
||||
return(E);
|
||||
}
|
||||
|
||||
DP H_vs_M (DP Delta, int N, int M)
|
||||
{
|
||||
// Assumes dE/dM = 0 = dE_0/dM + h, with dE_0/dM = E_0(M) - E_0 (M - 1)
|
||||
|
||||
DP H = 0.0;
|
||||
|
||||
if (2*M == N) H = 0.0;
|
||||
|
||||
else if (Delta <= 1.0) H = Ezero (Delta, N, M - 1) - Ezero (Delta, N, M);
|
||||
|
||||
return(H);
|
||||
}
|
||||
|
||||
DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref)
|
||||
{
|
||||
if (M < 0 || M > N/2 - 1) {
|
||||
cout << "M = " << M << endl;
|
||||
ABACUSerror("M out of bounds in HZmin.");
|
||||
}
|
||||
|
||||
if (Ezero_ref[M] == -1.0) Ezero_ref[M] = Ezero(Delta, N, M);
|
||||
if (Ezero_ref[M + 1] == -1.0) Ezero_ref[M + 1] = Ezero(Delta, N, M + 1);
|
||||
|
||||
return(Ezero_ref[M] - Ezero_ref[M + 1]);
|
||||
}
|
||||
|
||||
int M_vs_H (DP Delta, int N, DP HZ)
|
||||
{
|
||||
// Returns the value of M for given field HZ
|
||||
|
||||
if (HZ < 0.0) ABACUSerror("Please use a positive field in M_vs_H.");
|
||||
|
||||
else if (HZ == 0.0) return(N/2);
|
||||
|
||||
// Here, -1.0 is a sentinel value.
|
||||
Vect_DP Ezero(-1.0, N/2 + 1); // contains the GSE[M].
|
||||
|
||||
// We look for M s.t. HZmin[M] < HZ <= HZmin[M + 1]
|
||||
|
||||
int M_actual = N/4; // start somewhere in middle
|
||||
int M_step = N/8 - 1; // step
|
||||
DP HZmin_actual = 0.0;
|
||||
DP HZmax_actual = 0.0;
|
||||
bool M_found = false;
|
||||
|
||||
if (HZ >= 1.0 + Delta) M_actual = 0; // saturation
|
||||
|
||||
else {
|
||||
|
||||
HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
|
||||
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
|
||||
|
||||
while (!M_found) {
|
||||
|
||||
if (HZmin_actual > HZ) M_actual += M_step;
|
||||
else if (HZmax_actual <= HZ) M_actual -= M_step;
|
||||
|
||||
M_step = (M_step + 1)/2;
|
||||
|
||||
HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
|
||||
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
|
||||
|
||||
M_found = (HZmin_actual < HZ && HZ <= HZmax_actual);
|
||||
|
||||
//cout << "M_actual = " << M_actual << "\tM_step = " << M_step
|
||||
// << "\tHZmin_actual = " << HZmin_actual << "\tHZmax_actual = " << HZmax_actual << "\tHZ = " << HZ << "\t" << M_found << endl;
|
||||
}
|
||||
}
|
||||
//cout << "M found = " << M_actual << "\tHZmax = " << Ezero[M_actual] - Ezero[M_actual + 1] << "\tHZmin = " << Ezero[M_actual - 1] - Ezero[M_actual] << endl;
|
||||
|
||||
return(M_actual);
|
||||
}
|
||||
*/
|
||||
|
||||
DP Chemical_Potential (const ODSLF_Bethe_State& RefState)
|
||||
{
|
||||
return(-H_vs_M (RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown)); // - sign since E_{M+1} - E_M = -H
|
||||
|
|
|
@ -19,8 +19,6 @@ using namespace ABACUS;
|
|||
|
||||
namespace ABACUS {
|
||||
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, ODSLF_XXZ_Bethe_State& LeftState,
|
||||
//ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, ODSLF_XXZ_Bethe_State& LeftState,
|
||||
ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
{
|
||||
|
@ -39,7 +37,6 @@ namespace ABACUS {
|
|||
ME = exp(real(ln_Smin_ME (RefState, LeftState)));
|
||||
else if (whichDSF == 'z') {
|
||||
if (LeftState.base_id == RefState.base_id && LeftState.type_id == RefState.type_id && LeftState.id == RefState.id)
|
||||
//MEsq = RefState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RefState.base.Mdown/RefState.chain.Nsites), 2.0);
|
||||
ME = sqrt(RefState.chain.Nsites * 0.25) * (1.0 - 2.0*RefState.base.Mdown/RefState.chain.Nsites);
|
||||
else ME = exp(real(ln_Sz_ME (RefState, LeftState)));
|
||||
}
|
||||
|
@ -60,21 +57,18 @@ namespace ABACUS {
|
|||
if (whichDSF == 'Z') {
|
||||
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< LeftState.base_id << "\t" << LeftState.type_id << "\t" << LeftState.id;
|
||||
}
|
||||
else {
|
||||
DAT_outfile << endl << LeftState.E - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< LeftState.base_id << "\t" << LeftState.type_id << "\t" << LeftState.id;
|
||||
}
|
||||
} // 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 - RefState.E - (LeftState.base.Mdown - RefState.base.Mdown) * Chem_Pot);
|
||||
else if (fixed_iK) // data value is MEsq * omega:
|
||||
|
@ -83,5 +77,4 @@ namespace ABACUS {
|
|||
return(data_value);
|
||||
}
|
||||
|
||||
|
||||
} // namespace ABACUS
|
||||
|
|
|
@ -59,43 +59,7 @@ namespace ABACUS {
|
|||
|
||||
E0_Delta_eps = gstate2.E;
|
||||
}
|
||||
/*
|
||||
else if (Delta == 1.0) {
|
||||
// Define the ground state
|
||||
XXX_Bethe_State gstate(chain, gbase);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate.Compute_All(true);
|
||||
|
||||
E0_Delta = gstate.E;
|
||||
|
||||
// Define the ground state
|
||||
XXZ_gpd_Bethe_State gstate2(chain2, gbase2); // need XXZ_gpd here
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate2.Compute_All(true);
|
||||
|
||||
E0_Delta_eps = gstate2.E;
|
||||
}
|
||||
|
||||
else if (Delta > 1.0) {
|
||||
// Define the ground state
|
||||
XXZ_gpd_Bethe_State gstate(chain, gbase);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate.Compute_All(true);
|
||||
|
||||
E0_Delta = gstate.E;
|
||||
|
||||
// Define the ground state
|
||||
XXZ_gpd_Bethe_State gstate2(chain2, gbase2);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate2.Compute_All(true);
|
||||
|
||||
E0_Delta_eps = gstate2.E;
|
||||
}
|
||||
*/
|
||||
else ABACUSerror("Wrong anisotropy in ODSLF_S1_sumrule_factor.");
|
||||
|
||||
DP answer = 0.0;
|
||||
|
@ -117,8 +81,8 @@ namespace ABACUS {
|
|||
|
||||
DP sumrule = 0.0;
|
||||
|
||||
if (mporz == 'm' || mporz == 'p') sumrule = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/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 = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/N;
|
||||
|
||||
else if (mporz == 'z') sumrule = iK == 0 ? 1.0 : -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
|
||||
|
||||
|
@ -127,20 +91,15 @@ namespace ABACUS {
|
|||
|
||||
else ABACUSerror("option not implemented in ODSLF_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 ODSLF_S1_sumrule_factor (char mporz, DP Delta, int N, 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 = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/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 = - 2.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z)/N;
|
||||
|
||||
else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
|
||||
|
||||
|
@ -149,15 +108,12 @@ namespace ABACUS {
|
|||
|
||||
else ABACUSerror("option not implemented in ODSLF_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 Sumrule_Factor (char whichDSF, Heis_Bethe_State& RefState, DP Chem_Pot, bool fixed_iK, int iKneeded)
|
||||
DP Sumrule_Factor (char whichDSF, ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
|
||||
{
|
||||
DP sumrule_factor = 1.0;
|
||||
//if (!fixed_iK) {
|
||||
if (iKmin != iKmax) {
|
||||
if (whichDSF == 'Z') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'm')
|
||||
|
@ -170,12 +126,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, RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown, iKneeded);
|
||||
sumrule_factor = ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown, iKmax);
|
||||
sumrule_factor = ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites,
|
||||
RefState.base.Mdown, iKmax);
|
||||
else if (whichDSF == 'a') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'b') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
||||
|
@ -188,8 +143,8 @@ namespace ABACUS {
|
|||
return(sumrule_factor);
|
||||
}
|
||||
|
||||
//void Evaluate_F_Sumrule (char whichDSF, const ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax, const char* FFsq_Cstr, const char* FSR_Cstr)
|
||||
void Evaluate_F_Sumrule (string prefix, char whichDSF, const ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax)
|
||||
void Evaluate_F_Sumrule (string prefix, char whichDSF, const ODSLF_Bethe_State& RefState,
|
||||
DP Chem_Pot, int iKmin, int iKmax)
|
||||
{
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
|
@ -205,7 +160,6 @@ namespace ABACUS {
|
|||
if(infile.fail()) ABACUSerror("Could not open input file in Evaluate_F_Sumrule(ODSLF...).");
|
||||
|
||||
// We run through the data file to chech the f sumrule at each positive momenta:
|
||||
//Vect<DP> Sum_omega_FFsq(0.0, RefState.chain.Nsites/2 + 1); //
|
||||
Vect<DP> Sum_omega_FFsq(0.0, iKmax - iKmin + 1); //
|
||||
|
||||
DP omega, FF;
|
||||
|
@ -214,7 +168,6 @@ namespace ABACUS {
|
|||
|
||||
while (infile.peek() != EOF) {
|
||||
infile >> omega >> iK >> FF >> conv >> base_id >> type_id >> id;
|
||||
//if (iK > 0 && iK <= RefState.chain.Nsites/2) Sum_omega_FFsq[iK] += omega * FFsq;
|
||||
if (iK >= iKmin && iK <= iKmax) Sum_omega_FFsq[iK - iKmin] += omega * FF * FF;
|
||||
}
|
||||
|
||||
|
@ -227,15 +180,10 @@ namespace ABACUS {
|
|||
DP X_x = X_avg ('x', RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown);
|
||||
DP X_z = X_avg ('z', RefState.chain.Delta, RefState.chain.Nsites, RefState.base.Mdown);
|
||||
|
||||
/*
|
||||
outfile << 0 << "\t" << Sum_omega_FFsq[0] * S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites, X_x, X_z, 0);
|
||||
for (int i = 1; i <= RefState.chain.Nsites/2; ++i)
|
||||
outfile << endl << i << "\t" << Sum_omega_FFsq[i] * S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites, X_x, X_z, i);
|
||||
*/
|
||||
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
if (i > iKmin) outfile << endl;
|
||||
outfile << i << "\t" << Sum_omega_FFsq[i] * ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta, RefState.chain.Nsites, X_x, X_z, i);
|
||||
outfile << i << "\t" << Sum_omega_FFsq[i] * ODSLF_S1_sumrule_factor (whichDSF, RefState.chain.Delta,
|
||||
RefState.chain.Nsites, X_x, X_z, i);
|
||||
}
|
||||
|
||||
outfile.close();
|
||||
|
|
|
@ -31,11 +31,13 @@ namespace ABACUS {
|
|||
// Function definitions: class ODSLF_XXZ_Bethe_State
|
||||
|
||||
ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State ()
|
||||
: ODSLF_Bethe_State(), sinhlambda(ODSLF_Lambda(chain, 1)), coshlambda(ODSLF_Lambda(chain, 1)), tanhlambda(ODSLF_Lambda(chain, 1))
|
||||
: ODSLF_Bethe_State(), sinhlambda(ODSLF_Lambda(chain, 1)), coshlambda(ODSLF_Lambda(chain, 1)),
|
||||
tanhlambda(ODSLF_Lambda(chain, 1))
|
||||
{};
|
||||
|
||||
ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State (const ODSLF_XXZ_Bethe_State& RefState) // copy constructor
|
||||
: ODSLF_Bethe_State(RefState), sinhlambda(ODSLF_Lambda(RefState.chain, RefState.base)), coshlambda(ODSLF_Lambda(RefState.chain, RefState.base)),
|
||||
: ODSLF_Bethe_State(RefState), sinhlambda(ODSLF_Lambda(RefState.chain, RefState.base)),
|
||||
coshlambda(ODSLF_Lambda(RefState.chain, RefState.base)),
|
||||
tanhlambda(ODSLF_Lambda(RefState.chain, RefState.base))
|
||||
{
|
||||
// copy arrays into new ones
|
||||
|
@ -58,21 +60,26 @@ namespace ABACUS {
|
|||
//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 ODSLF_XXZ_Bethe_State constructor");
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0))
|
||||
ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
|
||||
}
|
||||
|
||||
ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& RefBase)
|
||||
: ODSLF_Bethe_State(RefChain, RefBase),
|
||||
sinhlambda(ODSLF_Lambda(RefChain, RefBase)), coshlambda(ODSLF_Lambda(RefChain, RefBase)), tanhlambda(ODSLF_Lambda(RefChain, RefBase))
|
||||
sinhlambda(ODSLF_Lambda(RefChain, RefBase)), coshlambda(ODSLF_Lambda(RefChain, RefBase)),
|
||||
tanhlambda(ODSLF_Lambda(RefChain, RefBase))
|
||||
{
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0))
|
||||
ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
|
||||
}
|
||||
|
||||
ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
|
||||
ODSLF_XXZ_Bethe_State::ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain,
|
||||
long long int base_id_ref, long long int type_id_ref)
|
||||
: ODSLF_Bethe_State(RefChain, base_id_ref, type_id_ref),
|
||||
sinhlambda(ODSLF_Lambda(chain, base)), coshlambda(ODSLF_Lambda(chain, base)), tanhlambda(ODSLF_Lambda(chain, base))
|
||||
{
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0))
|
||||
ABACUSerror("Delta out of range in ODSLF_XXZ_Bethe_State constructor");
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,13 +123,13 @@ namespace ABACUS {
|
|||
|
||||
for (int alpha = 0; alpha < base[i]; ++alpha) {
|
||||
|
||||
if(chain.par[i] == 1) lambda[i][alpha] = (tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites));
|
||||
else if (chain.par[i] == -1) lambda[i][alpha] = (-tan((PI * 0.5 * Ix2[i][alpha])/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis));
|
||||
if(chain.par[i] == 1)
|
||||
lambda[i][alpha] = (tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites));
|
||||
else if (chain.par[i] == -1)
|
||||
lambda[i][alpha] = (-tan((PI * 0.5 * Ix2[i][alpha])/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis));
|
||||
|
||||
else ABACUSerror("Invalid parities in Set_Free_lambdas.");
|
||||
|
||||
// if (lambda[i][alpha] == 0.0) lambda[i][alpha] = 0.001 * (1.0 + i) * (1.0 + alpha) / chain.Nsites; // some arbitrary starting point here...
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,7 +175,7 @@ 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)*/)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (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.
|
||||
|
@ -181,14 +188,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;
|
||||
}
|
||||
|
||||
|
@ -197,12 +206,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;
|
||||
|
@ -226,15 +237,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 * ODSLF_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 * ODSLF_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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -254,17 +271,22 @@ 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 * ODSLF_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 * ODSLF_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;
|
||||
|
||||
//if (is_nan(BE[j][alpha])) cout << "BE nan: " << j << "\t" << alpha << "\t" << lambda[j][alpha] << "\t" << tanhlambda[j][alpha] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,8 +304,8 @@ namespace ABACUS {
|
|||
(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)
|
||||
else if (chain.par[j] == -1)
|
||||
arg = -tan(0.5 *
|
||||
(-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]];
|
||||
|
||||
|
@ -305,21 +327,26 @@ 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 * ODSLF_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 * ODSLF_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.");
|
||||
|
||||
}
|
||||
|
||||
//cout << "Rapidity blows up !\t" << lambda[j][alpha] << "\t" << new_lambda << endl;
|
||||
}
|
||||
|
||||
return(new_lambda);
|
||||
|
@ -341,7 +368,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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,32 +380,6 @@ 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 ODSLF_XXZ_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
|
||||
{
|
||||
|
||||
|
@ -408,25 +410,29 @@ namespace ABACUS {
|
|||
for (int betap = 0; betap < base[kp]; ++betap) {
|
||||
if (!((j == kp) && (alpha == betap)))
|
||||
sum_hbar_XXZ
|
||||
+= ODSLF_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);
|
||||
+= ODSLF_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 * ODSLF_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 * ODSLF_hbar_XXZ (lambda[j][alpha], chain.Str_L[j], chain.par[j],
|
||||
chain.si_n_anis_over_2) - sum_hbar_XXZ);
|
||||
}
|
||||
|
||||
else {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
Gaudin_Red[index_jalpha][index_kbeta] =
|
||||
complex<DP> ((chain.par[j] * chain.par[k] == 1)
|
||||
? chain.si_n_anis_over_2[4]/(pow(sinhlambda[j][alpha] * coshlambda[k][beta]
|
||||
? chain.si_n_anis_over_2[4]
|
||||
/(pow(sinhlambda[j][alpha] * coshlambda[k][beta]
|
||||
- coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq)
|
||||
: chain.si_n_anis_over_2[4]/(-pow(coshlambda[j][alpha] * coshlambda[k][beta]
|
||||
: chain.si_n_anis_over_2[4]
|
||||
/(-pow(coshlambda[j][alpha] * coshlambda[k][beta]
|
||||
- sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) );
|
||||
else
|
||||
Gaudin_Red[index_jalpha][index_kbeta] = complex<DP> (ODSLF_ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k],
|
||||
Gaudin_Red[index_jalpha][index_kbeta] =
|
||||
complex<DP> (ODSLF_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++;
|
||||
|
@ -465,7 +471,8 @@ namespace ABACUS {
|
|||
|
||||
result = (nj == nk) ? 0.0 : ODSLF_fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk)]);
|
||||
|
||||
for (int a = 1; a < ABACUS::min(nj, nk); ++a) result += 2.0 * ODSLF_fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk) + 2*a]);
|
||||
for (int a = 1; a < ABACUS::min(nj, nk); ++a)
|
||||
result += 2.0 * ODSLF_fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk) + 2*a]);
|
||||
|
||||
result += ODSLF_fbar_XXZ(tanhlambda, parj*park, tannzetaover2[nj + nk]);
|
||||
}
|
||||
|
@ -490,7 +497,8 @@ namespace ABACUS {
|
|||
{
|
||||
DP result = (nj == nk) ? 0.0 : ODSLF_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 * ODSLF_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 * ODSLF_hbar_XXZ(lambda, fabs(nj - nk) + 2*a, parj*park, si_n_anis_over_2);
|
||||
|
||||
result += ODSLF_hbar_XXZ(lambda, nj + nk, parj*park, si_n_anis_over_2);
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@ using namespace ABACUS;
|
|||
|
||||
namespace ABACUS {
|
||||
|
||||
inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
@ -39,20 +39,15 @@ inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
|||
|
||||
arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
absarg = abs(arg);
|
||||
/*
|
||||
prod_temp *= 0.5 * //done later...
|
||||
((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
+ B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
|
||||
*/
|
||||
|
||||
prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
|
||||
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
|
||||
|
@ -64,10 +59,10 @@ inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
|||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
@ -85,19 +80,14 @@ inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B,
|
|||
|
||||
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));
|
||||
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);
|
||||
|
@ -107,10 +97,11 @@ inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B,
|
|||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
inline complex<DP> Fn_K (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a,
|
||||
ODSLF_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;
|
||||
|
@ -132,28 +123,31 @@ inline complex<DP> Fn_K (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a, ODSL
|
|||
+ A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
|
||||
));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
inline complex<DP> Fn_L (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a,
|
||||
ODSLF_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 (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
||||
{
|
||||
complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_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 ODSLF_XXZ_Chains in Smin matrix element.");
|
||||
if (A.chain != B.chain)
|
||||
ABACUSerror("Incompatible ODSLF_XXZ_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!");
|
||||
if (A.base.Mdown != B.base.Mdown + 1)
|
||||
ABACUSerror("Incompatible Mdown between the two states in Smin matrix element!");
|
||||
|
||||
// Compute the sinh and cosh of rapidities
|
||||
|
||||
|
@ -245,7 +239,8 @@ complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
|||
|
||||
index_b = 0;
|
||||
|
||||
one_over_A_sinhlambda_sq_plus_sinzetaover2sq = 1.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
one_over_A_sinhlambda_sq_plus_sinzetaover2sq =
|
||||
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])))
|
||||
|
@ -265,11 +260,15 @@ complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
|||
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));
|
||||
|
||||
Hm[index_a][index_b] = Fn_K_0_G_0 - (1.0 - 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
|
||||
|
@ -290,7 +289,8 @@ complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
|||
|
||||
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 += (1.0 - 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
|
||||
Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
|
@ -302,13 +302,8 @@ complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& 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]);
|
||||
|
||||
/*
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
*/
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1]
|
||||
- ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinzeta);
|
||||
|
@ -332,9 +327,8 @@ complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
|||
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
|
||||
|
|
|
@ -18,8 +18,8 @@ using namespace ABACUS;
|
|||
|
||||
namespace ABACUS {
|
||||
|
||||
inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
@ -40,20 +40,14 @@ inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
|||
|
||||
arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
absarg = abs(arg);
|
||||
/*
|
||||
prod_temp *= 0.5 *
|
||||
((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg)
|
||||
* B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
+ B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
|
||||
*/
|
||||
prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
|
||||
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));
|
||||
|
||||
}
|
||||
|
||||
|
@ -66,10 +60,10 @@ inline complex<DP> ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
|||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
@ -89,19 +83,14 @@ inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B,
|
|||
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);
|
||||
|
@ -111,10 +100,11 @@ inline complex<DP> ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B,
|
|||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
inline complex<DP> Fn_K (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a,
|
||||
ODSLF_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;
|
||||
|
@ -136,28 +126,31 @@ inline complex<DP> Fn_K (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a, ODSL
|
|||
+ A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
|
||||
));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
inline complex<DP> Fn_L (ODSLF_XXZ_Bethe_State& A, int j, int alpha, int a,
|
||||
ODSLF_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_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
||||
{
|
||||
complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXZ_Chain
|
||||
|
||||
if (A.chain != B.chain) ABACUSerror("Incompatible ODSLF_XXZ_Chains in Sz matrix element.");
|
||||
if (A.chain != B.chain)
|
||||
ABACUSerror("Incompatible ODSLF_XXZ_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.base.Mdown != B.base.Mdown)
|
||||
ABACUSerror("Incompatible Mdown between the two states in Sz matrix element!");
|
||||
|
||||
// Compute the sinh and cosh of rapidities
|
||||
|
||||
|
@ -250,7 +243,8 @@ complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
|||
|
||||
index_b = 0;
|
||||
|
||||
two_over_A_sinhlambda_sq_plus_sinzetaover2sq = 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
two_over_A_sinhlambda_sq_plus_sinzetaover2sq =
|
||||
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])))
|
||||
|
@ -270,11 +264,15 @@ complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
|||
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));
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - (-1.0 + 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
|
||||
|
@ -296,7 +294,8 @@ complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
|||
|
||||
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 += (-1.0 + 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ
|
||||
Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
|
@ -310,9 +309,11 @@ complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
|||
|
||||
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);
|
||||
|
@ -331,14 +332,10 @@ complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B)
|
|||
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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ABACUS
|
||||
|
|
|
@ -45,7 +45,6 @@ namespace ABACUS {
|
|||
*/
|
||||
|
||||
complex<DP> discr = sqrt((1.0/g_int + sumoneovereps[j]) * (1.0/g_int + sumoneovereps[j]) - 4.0 * sumSovereps[j]);
|
||||
//complex<DP> discr = sqrt(ABACUS::max(0.0, real((1.0/g_int + sumoneovereps[j]) * (1.0/g_int + sumoneovereps[j]) - 4.0 * sumSovereps[j])));
|
||||
Sjleft = 0.5 * (1.0/g_int + sumoneovereps[j] - discr);
|
||||
Sjright = 0.5 * (1.0/g_int + sumoneovereps[j] + discr);
|
||||
return(true);
|
||||
|
@ -93,8 +92,6 @@ namespace ABACUS {
|
|||
|
||||
// Re-solve for jmax:
|
||||
if (Solve_Richardson_Quad_S (g_int, epsilon, sumoneovereps, S, sumSovereps, jmax, Sleft, Sright)) {
|
||||
//if (leftroot[jmax] == true) S[jmax] = damping * Sleft + (1.0 - damping) * S[jmax];
|
||||
//else S[jmax] = damping * Sright + (1.0 - damping) * S[jmax];
|
||||
if (abs(S[jmax] - Sleft) < abs(S[jmax] - Sright)) S[jmax] = damping * Sleft + (1.0 - damping) * S[jmax];
|
||||
else S[jmax] = damping * Sright + (1.0 - damping) * S[jmax];
|
||||
}
|
||||
|
@ -104,14 +101,11 @@ namespace ABACUS {
|
|||
cout << " to " << S[jmax] << endl;
|
||||
|
||||
// Re-solve also for a random j, given by
|
||||
//int jrand = int(maxabsLHSRE * 1.0e+6) % Nlevels;
|
||||
int jrand = rand() % Nlevels;
|
||||
cout << "identified jrand = " << jrand << endl;
|
||||
cout << "S[jrand]: from " << S[jrand];
|
||||
|
||||
if (Solve_Richardson_Quad_S (g_int, epsilon, sumoneovereps, S, sumSovereps, jrand, Sleft, Sright)) {
|
||||
//if (leftroot[jrand] == true) S[jrand] = damping * Sleft + (1.0 - damping) * S[jrand];
|
||||
//else S[jrand] = damping * Sright + (1.0 - damping) * S[jrand];
|
||||
if (abs(S[jrand] - Sleft) < abs(S[jrand] - Sright)) S[jrand] = damping * Sleft + (1.0 - damping) * S[jrand];
|
||||
else S[jrand] = damping * Sright + (1.0 - damping) * S[jrand];
|
||||
}
|
||||
|
@ -120,18 +114,6 @@ namespace ABACUS {
|
|||
}
|
||||
cout << " to " << S[jrand] << endl;
|
||||
|
||||
/*
|
||||
for (int j = 0; j < Nlevels; ++j) {
|
||||
if (Solve_Richardson_Quad_S (g_int, epsilon, sumoneovereps, S, sumSovereps, j, Sleft, Sright)) {
|
||||
if (leftroot[j] == true) S[j] = damping * Sleft + (1.0 - damping) * S[j];
|
||||
else S[j] = damping * Sright + (1.0 - damping) * S[j];
|
||||
}
|
||||
else {
|
||||
ABACUSerror("Complex root.");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Recalculate all sums:
|
||||
for (int j = 0; j < Nlevels; ++j) {
|
||||
sumSovereps[j] = 0.0;
|
||||
|
@ -144,8 +126,6 @@ namespace ABACUS {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace ABACUS
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue