From e7dd24d337569112d7a2fee1ae2aa56b5000dfeb Mon Sep 17 00:00:00 2001 From: "J.-S. Caux" Date: Sun, 11 Feb 2018 10:01:56 +0100 Subject: [PATCH] Clean up sources up to (before) src/SCAN. --- ABACUS.org | 19 +- README.md | 7 +- src/LIEBLIN/LiebLin_Bethe_State.cc | 209 ++--- src/LIEBLIN/LiebLin_Chem_Pot.cc | 3 - src/LIEBLIN/LiebLin_Matrix_Element_Contrib.cc | 56 +- src/LIEBLIN/LiebLin_State_Ensemble.cc | 736 ++---------------- src/LIEBLIN/LiebLin_Sumrules.cc | 94 +-- src/LIEBLIN/LiebLin_Tgt0.cc | 394 +--------- src/LIEBLIN/LiebLin_Twisted_ln_Overlap.cc | 18 +- src/LIEBLIN/LiebLin_Twisted_lnnorm.cc | 3 +- src/LIEBLIN/LiebLin_Utils.cc | 6 +- src/LIEBLIN/LiebLin_ln_Overlap.cc | 99 +-- src/LIEBLIN/ln_Density_ME.cc | 20 +- src/LIEBLIN/ln_Psi_ME.cc | 10 +- src/LIEBLIN/ln_g2_ME.cc | 201 ++--- src/MATRIX/ludcmp_CX.cc | 7 +- src/MATRIX/tred2.cc | 1 - src/NRG/NRG_DME_Matrix_Block_builder.cc | 77 +- src/NRG/NRG_K_Weight_integrand.cc | 2 - src/NRG/NRG_State_Selector.cc | 125 +-- src/ODSLF/ODSLF.cc | 477 ++++-------- src/ODSLF/ODSLF_Chem_Pot.cc | 119 --- src/ODSLF/ODSLF_Matrix_Element_Contrib.cc | 7 - src/ODSLF/ODSLF_Sumrules.cc | 76 +- src/ODSLF/ODSLF_XXZ_Bethe_State.cc | 176 +++-- src/ODSLF/ln_Smin_ME_ODSLF_XXZ.cc | 526 +++++++------ src/ODSLF/ln_Sz_ME_ODSLF_XXZ.cc | 533 +++++++------ src/RICHARDSON/Richardson.cc | 32 +- 28 files changed, 1046 insertions(+), 2987 deletions(-) diff --git a/ABACUS.org b/ABACUS.org index 1c212ea..cf3b5f0 100644 --- a/ABACUS.org +++ b/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 diff --git a/README.md b/README.md index fab35d9..aaeb1ab 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/src/LIEBLIN/LiebLin_Bethe_State.cc b/src/LIEBLIN/LiebLin_Bethe_State.cc index e3318b4..7805f59 100644 --- a/src/LIEBLIN/LiebLin_Bethe_State.cc +++ b/src/LIEBLIN/LiebLin_Bethe_State.cc @@ -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(0,1)), Ix2_available(Vect(0, 1)), index_first_hole_to_right (Vect(0,1)), displacement (Vect(0,1)), - Ix2(Vect(0, 1)), lambdaoc(Vect(0.0, 1)), //BE(Vect(0.0, 1)), + Ix2(Vect(0, 1)), lambdaoc(Vect(0.0, 1)), S(Vect(0.0, 1)), dSdlambdaoc(Vect(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(0,N), Ix2_available(Vect(0, 2)), index_first_hole_to_right (Vect(0,N)), displacement (Vect(0,N)), - Ix2(Vect(0, N)), lambdaoc(Vect(0.0, N)), //BE(Vect(0.0, N)), + Ix2(Vect(0, N)), lambdaoc(Vect(0.0, N)), S(Vect(0.0, N)), dSdlambdaoc(Vect(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 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 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& 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 OriginStateIx2ordered = OriginStateIx2; - OriginStateIx2ordered.QuickSort(); - - // Set the state label: - Vect type_ref(0,1); - Vect M_ref(N, 1); - Vect 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 > Ix2old_ref(1); - Vect > Ix2exc_ref(1); - Ix2old_ref[0] = Vect(ABACUS::max(nexc_ref[0],1)); - Ix2exc_ref[0] = Vect(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& 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 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(navailable); index_first_hole_to_right = Vect(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)); } @@ -409,19 +343,14 @@ namespace ABACUS { void LiebLin_Bethe_State::Set_Free_lambdaocs() { if (cxL >= 1.0) - for (int a = 0; a < N; ++a) lambdaoc[a] = PI * Ix2[a]/cxL; + for (int a = 0; a < N; ++a) lambdaoc[a] = PI * Ix2[a]/cxL; // For small values of c, use better approximation using approximate zeroes of Hermite polynomials: see Gaudin eqn 4.71. if (cxL < 1.0) { - //DP sqrtcL = pow(cxL, 0.5); DP oneoversqrtcLN = 1.0/pow(cxL * N, 0.5); for (int a = 0; a < N; ++a) lambdaoc[a] = oneoversqrtcLN * PI * Ix2[a]; - - //for (int a = 0; a < N; ++a) lambdaoc[a] = sqrtcL * PI * Ix2[a]; // wrong values, correct scaling with c - //for (int a = 0; a < N; ++a) lambdaoc[a] = PI * Ix2[a]/(cxL + 2.0 * N); // set to minimal distance lattice } - //cout << "Set free lambdaocs to: " << endl << lambdaoc << endl; return; } @@ -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& 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 type_new = currentdata.type; @@ -768,16 +653,12 @@ namespace ABACUS { for (int i = 0; i < nexc_new[it]; ++i) { Ix2old_new[it][i] = currentdata.Ix2old[it][i + (i >= ihole)]; Ix2exc_new[it][i] = currentdata.Ix2exc[it][i + (i >= ipart)]; - } } - //cout << "Ix2old_new " << Ix2old_new[0] << endl; - //cout << "Ix2exc_new " << Ix2exc_new[0] << endl; + } State_Label_Data newdata (type_new, M_new, nexc_new, Ix2old_new, Ix2exc_new); (*this).Set_to_Label (Return_State_Label(newdata, OriginStateIx2)); - - //cout << "Obtained label " << (*this).label << endl; } void LiebLin_Bethe_State::Parity_Flip () diff --git a/src/LIEBLIN/LiebLin_Chem_Pot.cc b/src/LIEBLIN/LiebLin_Chem_Pot.cc index 70c40d6..815056f 100644 --- a/src/LIEBLIN/LiebLin_Chem_Pot.cc +++ b/src/LIEBLIN/LiebLin_Chem_Pot.cc @@ -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)); } diff --git a/src/LIEBLIN/LiebLin_Matrix_Element_Contrib.cc b/src/LIEBLIN/LiebLin_Matrix_Element_Contrib.cc index 39fee7c..f9f8a0a 100644 --- a/src/LIEBLIN/LiebLin_Matrix_Element_Contrib.cc +++ b/src/LIEBLIN/LiebLin_Matrix_Element_Contrib.cc @@ -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') diff --git a/src/LIEBLIN/LiebLin_State_Ensemble.cc b/src/LIEBLIN/LiebLin_State_Ensemble.cc index aaa3b5f..40cc901 100644 --- a/src/LIEBLIN/LiebLin_State_Ensemble.cc +++ b/src/LIEBLIN/LiebLin_State_Ensemble.cc @@ -30,13 +30,6 @@ namespace ABACUS { : nstates(nstates_req), state(Vect(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& weight_ref) - : nstates(nstates_req), state(Vect(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] < 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"); - } + 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_found[Nfound] = 2.0 * L * x.Return_Value(rho.lambda[i]); + 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.Return_Value(rho.lambda[i]); - Ix2_left = floor(Ix2_found[Nfound]); - Ix2_left -= (Ix2_left + N + 1)%2 ? 1 : 0; //adjust parity + 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 + Ix2_right = ceil(Ix2_found[Nfound]); + Ix2_right += (Ix2_right + N + 1)%2 ? 1 : 0; //adjust parity - int Ix2_in = (Ix2_found[Nfound] > 0 ? Ix2_left : Ix2_right); - int Ix2_out = (Ix2_found[Nfound] > 0 ? Ix2_right : Ix2_left); - cout << rho.lambda[i] << "\t" << x.Return_Value(rho.lambda[i]) << "\t" << Ix2_found[Nfound] << endl; + int Ix2_in = (Ix2_found[Nfound] > 0 ? Ix2_left : Ix2_right); + int Ix2_out = (Ix2_found[Nfound] > 0 ? Ix2_right : Ix2_left); + cout << rho.lambda[i] << "\t" << x.Return_Value(rho.lambda[i]) << "\t" << Ix2_found[Nfound] << endl; - //choose the saddle point state and remember the uncertain choices - if(Ix2_found[Nfound] - Ix2_left < 0.5) { - state[0].Ix2[Nfound] = Ix2_left; - state[1].Ix2[Nfound] = Ix2_left; - state[2].Ix2[Nfound] = Ix2_left; - state[3].Ix2[Nfound] = Ix2_left; - } - else if (Ix2_right - Ix2_found[Nfound] < 0.5) { - state[0].Ix2[Nfound] = Ix2_right; - state[1].Ix2[Nfound] = Ix2_right; - state[2].Ix2[Nfound] = Ix2_right; - state[3].Ix2[Nfound] = Ix2_right; - } - else { //it's a kind of magic: the zeroth goes in whle the first goes out, the second goes left if the third goes right - state[0].Ix2[Nfound] = Ix2_in; - state[1].Ix2[Nfound] = Ix2_out; - state[2+change].Ix2[Nfound] = Ix2_left; - state[2+!change].Ix2[Nfound] = Ix2_right; - change = !change; - ++n_moves; - } - Nfound++; - } + //choose the saddle point state and remember the uncertain choices + if(Ix2_found[Nfound] - Ix2_left < 0.5) { + state[0].Ix2[Nfound] = Ix2_left; + state[1].Ix2[Nfound] = Ix2_left; + state[2].Ix2[Nfound] = Ix2_left; + state[3].Ix2[Nfound] = Ix2_left; + } + else if (Ix2_right - Ix2_found[Nfound] < 0.5) { + state[0].Ix2[Nfound] = Ix2_right; + state[1].Ix2[Nfound] = Ix2_right; + state[2].Ix2[Nfound] = Ix2_right; + state[3].Ix2[Nfound] = Ix2_right; + } + else { + //it's a kind of magic: the zeroth goes in whle the first goes out, + //the second goes left if the third goes right + state[0].Ix2[Nfound] = Ix2_in; + state[1].Ix2[Nfound] = Ix2_out; + state[2+change].Ix2[Nfound] = Ix2_left; + state[2+!change].Ix2[Nfound] = Ix2_right; + change = !change; + ++n_moves; + } + Nfound++; + } } - //cout << "\ti = " << i << "\tintegral = " << integral << "\tNfound = " << Nfound << endl; } - //cout << endl; //fix state[3] and state[4] for(int i=0; i Ix2_found(0.0, N); - int Ix2_left, Ix2_right; - Vect Ix2(N); - Vect Ix2_uncertain(0, N); - Vect 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 > Ix2states(Ix2, n_states_raw); - Vect 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> 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 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(rhostate, nstates); - weight = Vect(nstates); - - DP sum_weight = 0.0; - for(int i=0; i 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 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 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 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 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 Ix2(N); - Vect 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 > Ix2states(Ix2, n_states_raw); - - Vect hole_position(0, 0.5*n); - int hole_index = 0; - for(int i=N/2 + N%2; i> 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 > Ix2states(Ix2, n_states_raw); - - Vect hole_position(0, n); - int hole_index = 0; - for(int i=0; i> 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 state_raw = Vect(rhostate, n_states_raw); - Vect 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 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 0.01) ++nstates; - - nstates = ABACUS::min(n_states_raw, 21); - - cout << nstates << endl; - - state = Vect(rhostate, nstates); - weight = Vect(nstates); - - DP sum_weight = 0.0; - for(int i=0; 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 > Ix2states1mod(nrstates1mod); - for (int nrs = 0; nrs < nrstates1mod; ++nrs) Ix2states1mod[nrs] = Vect (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 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 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(rhostate, nstates); - weight = Vect (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 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 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 Ix2_exact(N); - Vect 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 > Ix2states1mod(nrstates1mod); - for (int nrs = 0; nrs < nrstates1mod; ++nrs) Ix2states1mod[nrs] = Vect (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 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 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(rhostate, nstates_req); - weight = Vect (nstates_req); - - for (int ns = 0; ns < nstates_req; ++ns) { - weight[ns] = rawweight[nrstates1mod - 1 - ns]/weightnorm; - state[ns].Ix2 = Ix2states1mod[index[nrstates1mod - 1 - ns] ]; - state[ns].Set_Label_from_Ix2 (rhostate.Ix2); - state[ns].Compute_All(true); - } - } - */ - LiebLin_Diagonal_State_Ensemble& LiebLin_Diagonal_State_Ensemble::operator= (const LiebLin_Diagonal_State_Ensemble& rhs) { if (this != &rhs) { @@ -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 (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); } diff --git a/src/LIEBLIN/LiebLin_Sumrules.cc b/src/LIEBLIN/LiebLin_Sumrules.cc index 97bf38f..1262b48 100644 --- a/src/LIEBLIN/LiebLin_Sumrules.cc +++ b/src/LIEBLIN/LiebLin_Sumrules.cc @@ -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 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,21 +125,13 @@ 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); + * RefState.L/((4.0 * PI * PI * i * i)/(RefState.L * RefState.L) - Chem_Pot + 4.0 * RefState.c_int * RefState.N/RefState.L); } } @@ -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); } } diff --git a/src/LIEBLIN/LiebLin_Tgt0.cc b/src/LIEBLIN/LiebLin_Tgt0.cc index aa122b8..5cb5126 100644 --- a/src/LIEBLIN/LiebLin_Tgt0.cc +++ b/src/LIEBLIN/LiebLin_Tgt0.cc @@ -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 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 rho(0.0, Nptsx); - Vect 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 xparticle(RefState.N); - //for (int i = 0; i < RefState.N; ++i) xparticle[i] = RefState.Ix2[i]/(2.0* RefState.L); - Vect 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 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 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 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); @@ -477,7 +93,7 @@ namespace ABACUS { DP answer = 0.0; for (int i = 0; i < RefState.N; ++i) answer += 1.0/(pow(lambdaoc - RefState.lambdaoc[i], 2.0) + delta*delta); - answer *= delta/(PI * RefState.L); + answer *= delta/(PI * RefState.L); return(answer); } diff --git a/src/LIEBLIN/LiebLin_Twisted_ln_Overlap.cc b/src/LIEBLIN/LiebLin_Twisted_ln_Overlap.cc index fde1f3c..7c6584c 100644 --- a/src/LIEBLIN/LiebLin_Twisted_ln_Overlap.cc +++ b/src/LIEBLIN/LiebLin_Twisted_ln_Overlap.cc @@ -51,14 +51,16 @@ namespace ABACUS { return(1.0/Fn_V (j, -sign, lstate_lambdaoc, rstate)); } - complex LiebLin_Twisted_ln_Overlap (DP expbeta, Vect lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate) + complex LiebLin_Twisted_ln_Overlap (DP expbeta, Vect lstate_lambdaoc, + DP lstate_lnnorm, LiebLin_Bethe_State& rstate) { Vect > lstate_lambdaoc_CX(lstate_lambdaoc.size()); for (int i = 0; i < lstate_lambdaoc.size(); ++i) lstate_lambdaoc_CX[i] = complex(lstate_lambdaoc[i]); return(LiebLin_Twisted_ln_Overlap (complex(expbeta), lstate_lambdaoc_CX, lstate_lnnorm, rstate)); } - complex LiebLin_Twisted_ln_Overlap (complex expbeta, Vect > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate) + complex LiebLin_Twisted_ln_Overlap (complex expbeta, Vect > 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 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(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)); } diff --git a/src/LIEBLIN/LiebLin_Twisted_lnnorm.cc b/src/LIEBLIN/LiebLin_Twisted_lnnorm.cc index 9701aa4..1e3b925 100644 --- a/src/LIEBLIN/LiebLin_Twisted_lnnorm.cc +++ b/src/LIEBLIN/LiebLin_Twisted_lnnorm.cc @@ -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); diff --git a/src/LIEBLIN/LiebLin_Utils.cc b/src/LIEBLIN/LiebLin_Utils.cc index 909c46c..abacaad 100644 --- a/src/LIEBLIN/LiebLin_Utils.cc +++ b/src/LIEBLIN/LiebLin_Utils.cc @@ -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(N+1.0))); - for(int i =N/2; i Fn_V (int j, int sign, Vect >& lstate_lambdaoc, LiebLin_Bethe_State& rstate) - { - complex result_num = 1.0; - complex result_den = 1.0; - - complex signcx = complex(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 LiebLin_ln_Overlap (Vect 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 lndetOmega = lndet_LU_CX_dstry(Omega); - //cout << "lndetOmega = " << lndetOmega << endl; - // Prefactors: complex ln_prod_d_mu = II * 0.5 * rstate.cxL * rstate.lambdaoc.sum(); complex 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 LiebLin_ln_Overlap (Vect > 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 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 ln_ddalpha_sigma = lndet_LU_CX_dstry(one_plus_U); - - complex ln_prod_V = 0.0; - for (int a = 0; a < rstate.N; ++a) ln_prod_V += log(Vplus[a] - Vminus[a]); - - complex 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(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 diff --git a/src/LIEBLIN/ln_Density_ME.cc b/src/LIEBLIN/ln_Density_ME.cc index cc82157..3e91d81 100644 --- a/src/LIEBLIN/ln_Density_ME.cc +++ b/src/LIEBLIN/ln_Density_ME.cc @@ -21,17 +21,12 @@ namespace ABACUS { complex Fn_V (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate) { - //complex result_num = 1.0; - //complex result_den = 1.0; complex 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(lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a])); + if (m != a) ln_Fn_Prod[a] += log(complex(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 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)); diff --git a/src/LIEBLIN/ln_Psi_ME.cc b/src/LIEBLIN/ln_Psi_ME.cc index bffb8e4..36d4ae3 100644 --- a/src/LIEBLIN/ln_Psi_ME.cc +++ b/src/LIEBLIN/ln_Psi_ME.cc @@ -66,16 +66,16 @@ namespace ABACUS { complex 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((rstate.lambdaoc[a] - rstate.lambdaoc[b]) * (rstate.lambdaoc[a] - rstate.lambdaoc[b])) + 1.0); + ln_prod_lambdaocsq_plus_one += log(complex((rstate.lambdaoc[a] - rstate.lambdaoc[b]) + * (rstate.lambdaoc[a] - rstate.lambdaoc[b])) + 1.0); complex 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(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 diff --git a/src/LIEBLIN/ln_g2_ME.cc b/src/LIEBLIN/ln_g2_ME.cc index 321516d..3da8653 100644 --- a/src/LIEBLIN/ln_g2_ME.cc +++ b/src/LIEBLIN/ln_g2_ME.cc @@ -20,173 +20,66 @@ using namespace std; using namespace ABACUS; namespace ABACUS { -/* - complex ln_g2_ME_old_jacopo (LiebLin_Bethe_State& mu, LiebLin_Bethe_State& lambda) + + complex Fn_V_g2 (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate) { + complex result = 1.0; - 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 log_themp; - complex 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 m = 0; m < lstate.N; ++m) { + result *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II)/(rstate.lambdaoc[m] - rstate.lambdaoc[j] + II); } - - for(int j=0; j < mu.N; ++j){ - for(int k=0; k 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)); + return(result); } -*/ - complex Fn_V_g2 (int j, LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate) - { - //complex result_num = 1.0; - //complex result_den = 1.0; - complex result = 1.0; - for (int m = 0; m < lstate.N; ++m) { - //result_num *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II); - //result_den *= (rstate.lambdaoc[m] - rstate.lambdaoc[j] + II); - result *= (lstate.lambdaoc[m] - rstate.lambdaoc[j] + II)/(rstate.lambdaoc[m] - rstate.lambdaoc[j] + II); - } - //return(result_num/result_den); - return(result); + complex ln_g2_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate) + { + // Computes the log of the density operator \rho(x = 0) matrix element between lstate and rstate. + + // If we have lstate == rstate, density matrix element = 0: + if (lstate.Ix2 == rstate.Ix2) return(-200.); + + SQMat_DP one_plus_U (0.0, lstate.N); + + Vect_CX Vplus (0.0, lstate.N); // contains V^+_j; V^-_j is the conjugate + Vect_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 = 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); + ln_Fn_Prod[a] = 0.0;; + for (int m = 0; m < lstate.N; ++m) + if (m != a) ln_Fn_Prod[a] += log(complex(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]) + * ((lstate.lambdaoc[a] - rstate.lambdaoc[a])*real(exp(ln_Fn_Prod[a])) + * (rstate.Kernel(a,b) - rKern[b]) + rKern[b]); - complex ln_g2_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate) - { - // Computes the log of the density operator \rho(x = 0) matrix element between lstate and rstate. - - // If we have lstate == rstate, density matrix element = 0: - - - if (lstate.Ix2 == rstate.Ix2) return(-200.); - - - - - SQMat_DP one_plus_U (0.0, lstate.N); - - Vect_CX Vplus (0.0, lstate.N); // contains V^+_j; V^-_j is the conjugate - //Vect_DP Fn_Prod (0.0, lstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j) - // From ABACUS++G_3 onwards: use logs to stabilize numerical values at small c, at the cost of execution speed. - Vect_CX ln_Fn_Prod (0.0, lstate.N); // product_{m\neq j} (\mu_m - \lambdaoc_j)/(\lambdaoc_m - \lambdaoc_j) - Vect_DP rKern (0.0, lstate.N); // K(lambdaoc_j - lambdaoc_(p == arbitrary)) - - //int p = 0; - int p = rstate.N/2-1; // choice doesn't matter, see 1990_Slavnov_TMP_82 after (3.8). Choose rapidity around the middle. - - - DP c_int = rstate.c_int; - - DP Eout = log(pow(lstate.E - rstate.E,2.)) - (2)*log(c_int) - log(2*lstate.N); - - for (int a = 0; a < lstate.N; ++a) { - Vplus[a] = Fn_V_g2 (a, lstate, rstate); - //Fn_Prod[a] = 1.0; - ln_Fn_Prod[a] = 0.0;; - for (int m = 0; m < lstate.N; ++m) - //if (m != a) Fn_Prod[a] *= (lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a]); - if (m != a) ln_Fn_Prod[a] += log(complex(lstate.lambdaoc[m] - rstate.lambdaoc[a])/(rstate.lambdaoc[m] - rstate.lambdaoc[a])); - rKern[a] = rstate.Kernel (a, p); - } - - for (int a = 0; a < lstate.N; ++a) - for (int b = 0; b < lstate.N; ++b) - one_plus_U[a][b] = (a == b ? 1.0 : 0.0) + 0.5 * 1./imag(Vplus[a]) - //* Fn_Prod[a] * (rstate.Kernel(a,b) - rKern[b]); - * ((lstate.lambdaoc[a] - rstate.lambdaoc[a])*real(exp(ln_Fn_Prod[a])) * (rstate.Kernel(a,b) - rKern[b]) + rKern[b]); - - complex ln_ddalpha_sigma = lndet_LU_dstry(one_plus_U); - - complex ln_prod_V = 0.0; - for (int a = 0; a < lstate.N; ++a) ln_prod_V += log(2.0 * II * imag(Vplus[a])); - - complex ln_prod_2 = 0.0; - for (int a = 0; a < lstate.N; ++a) - for (int b = 0; b < lstate.N; ++b) - ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate.lambdaoc[a] - rstate.lambdaoc[b])); - - //cout << "ln_Fn_Prod = " << ln_Fn_Prod << endl; - //cout << endl << ln_ddalpha_sigma << "\t" << ln_prod_V << "\t" << ln_prod_2 << "\t" << - log(2.0 * II * imag(Vplus[p])) << "\t" << - 0.5 * (lstate.lnnorm + rstate.lnnorm) << "\t" << ln_ddalpha_sigma + ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p])) - 0.5 * (lstate.lnnorm + rstate.lnnorm) << endl; - - ln_ddalpha_sigma += ln_prod_V + ln_prod_2 - log(2.0 * II * imag(Vplus[p])); - - return (log(II) + Eout + ln_ddalpha_sigma - 0.5 * (lstate.lnnorm + rstate.lnnorm)); - } + complex ln_ddalpha_sigma = lndet_LU_dstry(one_plus_U); + complex ln_prod_V = 0.0; + for (int a = 0; a < lstate.N; ++a) ln_prod_V += log(2.0 * II * imag(Vplus[a])); + complex ln_prod_2 = 0.0; + for (int a = 0; a < lstate.N; ++a) + for (int b = 0; b < lstate.N; ++b) + ln_prod_2 += log((rstate.lambdaoc[a] - rstate.lambdaoc[b] + II)/(lstate.lambdaoc[a] - rstate.lambdaoc[b])); + 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 diff --git a/src/MATRIX/ludcmp_CX.cc b/src/MATRIX/ludcmp_CX.cc index 33f6308..a70d998 100644 --- a/src/MATRIX/ludcmp_CX.cc +++ b/src/MATRIX/ludcmp_CX.cc @@ -6,7 +6,6 @@ void ABACUS::ludcmp_CX (SQMat_CX& a, Vect_INT& indx, DP& d) const complex TINY = 1.0e-200; int i, j, k; int imax = 0; - // DP big, dum, sum, temp; complex 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; } diff --git a/src/MATRIX/tred2.cc b/src/MATRIX/tred2.cc index c1350c2..356ae1d 100644 --- a/src/MATRIX/tred2.cc +++ b/src/MATRIX/tred2.cc @@ -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]; diff --git a/src/NRG/NRG_DME_Matrix_Block_builder.cc b/src/NRG/NRG_DME_Matrix_Block_builder.cc index dab808a..8d989a7 100644 --- a/src/NRG/NRG_DME_Matrix_Block_builder.cc +++ b/src/NRG/NRG_DME_Matrix_Block_builder.cc @@ -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,8 +130,9 @@ 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 - << " Newton step; diffsq = " << Scanstate.diffsq << endl; + 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 for (int nrglabel_right = nrglabel_right_begin; nrglabel_right <= nrglabel_right_end; ++nrglabel_right) { @@ -136,8 +144,9 @@ 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 - << " Newton step; diffsq = " << Scanstate.diffsq << endl; + 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 diff --git a/src/NRG/NRG_K_Weight_integrand.cc b/src/NRG/NRG_K_Weight_integrand.cc index 603938a..67161a0 100644 --- a/src/NRG/NRG_K_Weight_integrand.cc +++ b/src/NRG/NRG_K_Weight_integrand.cc @@ -43,6 +43,4 @@ namespace ABACUS { return(value); } - - } // namespace ABACUS diff --git a/src/NRG/NRG_State_Selector.cc b/src/NRG/NRG_State_Selector.cc index 94cb1d4..4945d94 100644 --- a/src/NRG/NRG_State_Selector.cc +++ b/src/NRG/NRG_State_Selector.cc @@ -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 >& 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 >& 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 >& 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 diff --git a/src/ODSLF/ODSLF.cc b/src/ODSLF/ODSLF.cc index c9d426b..2240c60 100644 --- a/src/ODSLF/ODSLF.cc +++ b/src/ODSLF/ODSLF.cc @@ -37,7 +37,8 @@ namespace ABACUS { } ODSLF_Base::ODSLF_Base (const Heis_Chain& RefChain, int M) - : Mdown(M), Nrap(Vect(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect(RefChain.Nstrings)), Ix2_max(Vect(RefChain.Nstrings)) + : Mdown(M), Nrap(Vect(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect(RefChain.Nstrings)), + Ix2_max(Vect(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& Nrapidities) - : Mdown(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect(RefChain.Nstrings)), Ix2_max(Vect(RefChain.Nstrings)), - id (0LL) + : Mdown(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect(RefChain.Nstrings)), + Ix2_max(Vect(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(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect(RefChain.Nstrings)), Ix2_max(Vect(RefChain.Nstrings)), - id (id_ref) + : Mdown(0), Nrap(Vect(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect(RefChain.Nstrings)), + Ix2_max(Vect(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,8 +157,9 @@ namespace ABACUS { sum2 = 0.0; - sum2 += (RefChain.Str_L[j] == RefChain.Str_L[k]) ? 0.0 : 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k]) - - 0.5 * fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) * RefChain.anis)); + sum2 += (RefChain.Str_L[j] == RefChain.Str_L[k]) ? 0.0 : + 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k]) + - 0.5 * fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) * RefChain.anis)); sum2 += 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k]) - 0.5 * (RefChain.Str_L[j] + RefChain.Str_L[k]) * RefChain.anis)); @@ -179,8 +170,9 @@ namespace ABACUS { sum1 += (Nrap[k] - ((j == k) ? 1 : 0)) * sum2; } - Ix2_infty[j] = (1.0/PI) * fabs(RefChain.Nsites * 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j]) - - 0.5 * RefChain.Str_L[j] * RefChain.anis)) - sum1); + Ix2_infty[j] = (1.0/PI) * fabs(RefChain.Nsites * 2.0 + * atan(tan(0.25 * PI * (1.0 + RefChain.par[j]) + - 0.5 * RefChain.Str_L[j] * RefChain.anis)) - sum1); } // The Ix2_infty are now set. @@ -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& possible_type_id, int& nfound, int base_level, Vect& Nexcitations) + void ODSLF_Base::Scan_for_Possible_Types (Vect& possible_type_id, int& nfound, + int base_level, Vect& 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(M,1)), Nraptot(M), Ix2(new int*[1]) // single type of string here - //: Ix2 (Vect > (1)) { Ix2[0] = new int[M]; - //Ix2[0] = Vect (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 > (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 (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 > (RefConfig.Ix2.size()); - for (int i = 0; i < RefConfig.Ix2.size(); ++i) { - Ix2[i] = Vect (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; @@ -461,7 +403,7 @@ namespace ABACUS { for (int i = 0; i < Nstrings; ++i) for (int j = 0; j < Nrap[i]; ++j) Ix2[i][j] = RefConfig.Ix2[i][j]; - } + } return(*this); } @@ -494,22 +436,17 @@ namespace ABACUS { ODSLF_Lambda::ODSLF_Lambda (const Heis_Chain& RefChain, int M) : Nstrings(1), Nrap(Vect(M,1)), Nraptot(M), lambda(new DP*[1]) // single type of string here - //: lambda(Vect > (1)) { lambda[0] = new DP[M]; - //lambda[0] = Vect (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 > (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 (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 > (RefLambda.lambda.size()); - for (int i = 0; i < RefLambda.lambda.size(); ++i) { - lambda[i] = Vect (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; @@ -541,7 +469,7 @@ namespace ABACUS { for (int i = 0; i < Nstrings; ++i) for (int j = 0; j < Nrap[i]; ++j) lambda[i][j] = RefLambda.lambda[i][j]; - } + } return(*this); } @@ -586,15 +514,16 @@ namespace ABACUS { (*this) = ODSLF_Ix2_Offsets(RefBase, nparticles); } - ODSLF_Ix2_Offsets::ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, Vect nparticles) // sets all tableaux to empty ones, with nparticles at each level - : base(RefBase), Tableau(Vect (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 nparticles) + // sets all tableaux to empty ones, with nparticles at each level + : base(RefBase), Tableau(Vect (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,35 +531,42 @@ 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) - << "\t" << (nparticles[2*base_level + 3] > 0) << "\t" - << (nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2) - << endl; - ABACUSerror("nparticles too large in Ix2_Offsets constructor."); - } + 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) + << endl; + ABACUSerror("nparticles too large in Ix2_Offsets constructor."); + } // Check sum of rapidities @@ -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 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. - test1 += arg; - test3 += arg * arg * arg; // to make sure that all I's are symmetrical... - } - if (!(symmetric_state && (test1 == 0) && (test3 == 0))) symmetric_state = false; - } - //} - /* - else if (chain.Delta > 1.0) { - // For the gapped antiferromagnet, we check symmetry *excluding* the Ix2_max values - // The state is then inadmissible is symmetric && -Ix2_max occupied - for (int j = 0; j < chain.Nstrings; ++j) { - test1 = 0; - test3 = 0; - for (int alpha = 0; alpha < base[j]; ++alpha) { - arg = (Ix2[j][alpha] != chain.Nsites - && abs(Ix2[j][alpha]) != base.Ix2_max[j]) ? Ix2[j][alpha] : 0; // since Ix2 = N is same as Ix2 = -N by periodicity, this is symmetric. - test1 += arg; - test3 += arg * arg * arg; // to make sure that all I's are symmetrical... - } - if (!(symmetric_state && (test1 == 0) && (test3 == 0))) symmetric_state = false; + for (int j = 0; j < chain.Nstrings; ++j) { + test1 = 0; + test3 = 0; + for (int alpha = 0; alpha < base[j]; ++alpha) { + // 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; } - */ return symmetric_state; } @@ -1134,22 +975,18 @@ namespace ABACUS { jmax = j; alphamax = alpha; maxterm = pow(BE[j][alpha], 2.0)/chain.Nsites; - } + } } diffsq /= DP(chain.Nsites); } 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; @@ -1467,23 +1292,21 @@ namespace ABACUS { for (int i = 0; i < 4; ++i) oneoverP[i] = 1.0/(1.0 + i*i); for (int j = 0; j < chain.Nstrings; ++j) for (int alpha = 0; alpha < base[j]; ++alpha) { - rap[0] = lambda1[j][alpha]; - rap[1] = lambda2[j][alpha]; - rap[2] = lambda3[j][alpha]; - rap[3] = lambda4[j][alpha]; - //rap[4] = lambda5[j][alpha]; + rap[0] = lambda1[j][alpha]; + rap[1] = lambda2[j][alpha]; + rap[2] = lambda3[j][alpha]; + rap[3] = lambda4[j][alpha]; - polint (oneoverP, rap, 0.0, lambda[j][alpha], deltalambda); - - //cout << j << "\t" << alpha << "\t" << rap << "\t" << lambda[j][alpha] << "\t" << deltalambda << endl; - } + polint (oneoverP, rap, 0.0, lambda[j][alpha], deltalambda); + } (*this).Iterate_BAE(); } 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 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 diff --git a/src/ODSLF/ODSLF_Chem_Pot.cc b/src/ODSLF/ODSLF_Chem_Pot.cc index b29dc13..0372e3c 100644 --- a/src/ODSLF/ODSLF_Chem_Pot.cc +++ b/src/ODSLF/ODSLF_Chem_Pot.cc @@ -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 diff --git a/src/ODSLF/ODSLF_Matrix_Element_Contrib.cc b/src/ODSLF/ODSLF_Matrix_Element_Contrib.cc index c87fbfe..4a82b62 100644 --- a/src/ODSLF/ODSLF_Matrix_Element_Contrib.cc +++ b/src/ODSLF/ODSLF_Matrix_Element_Contrib.cc @@ -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 diff --git a/src/ODSLF/ODSLF_Sumrules.cc b/src/ODSLF/ODSLF_Sumrules.cc index 3a8480f..71ff510 100644 --- a/src/ODSLF/ODSLF_Sumrules.cc +++ b/src/ODSLF/ODSLF_Sumrules.cc @@ -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 Sum_omega_FFsq(0.0, RefState.chain.Nsites/2 + 1); // Vect 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(); diff --git a/src/ODSLF/ODSLF_XXZ_Bethe_State.cc b/src/ODSLF/ODSLF_XXZ_Bethe_State.cc index c38e3bc..ca75948 100644 --- a/src/ODSLF/ODSLF_XXZ_Bethe_State.cc +++ b/src/ODSLF/ODSLF_XXZ_Bethe_State.cc @@ -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,8 +175,8 @@ namespace ABACUS { bool higher_string_on_zero = false; for (int j = 0; j < chain.Nstrings; ++j) { // The following line puts answer to true if there is at least one higher string with zero Ix2 - for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] >= 2) /*&& !(chain.Str_L[j] % 2)*/) - higher_string_on_zero = true; + for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] >= 2)) + 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,17 +237,23 @@ namespace ABACUS { for (int beta = 0; beta < base[k]; ++beta) { if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) sumtheta += (chain.par[j] == chain.par[k]) - ? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2])) - : - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ; - else sumtheta += 0.5 * 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; - } + } void ODSLF_XXZ_Bethe_State::Compute_BE () { @@ -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; } } @@ -277,15 +299,15 @@ namespace ABACUS { DP arg = 0.0; if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]] - * tan(0.5 * - //(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites - (2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha]) - ); + * tan(0.5 * + //(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites + (2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha]) + ); - else if (chain.par[j] == -1) arg = -tan(0.5 * - //(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites) - (-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha])) - /chain.ta_n_anis_over_2[chain.Str_L[j]]; + 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]]; if (fabs(arg) < 1.0) { new_lambda = atanh(arg); @@ -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 >& Gaudin_Red) { @@ -408,26 +410,30 @@ 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 ( 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 ( 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 ((chain.par[j] * chain.par[k] == 1) - ? chain.si_n_anis_over_2[4]/(pow(sinhlambda[j][alpha] * coshlambda[k][beta] - - coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) - : chain.si_n_anis_over_2[4]/(-pow(coshlambda[j][alpha] * coshlambda[k][beta] - - sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) ); + ? chain.si_n_anis_over_2[4] + /(pow(sinhlambda[j][alpha] * coshlambda[k][beta] + - coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) + : chain.si_n_anis_over_2[4] + /(-pow(coshlambda[j][alpha] * coshlambda[k][beta] + - sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) ); else - Gaudin_Red[index_jalpha][index_kbeta] = complex (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)); + Gaudin_Red[index_jalpha][index_kbeta] = + complex (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); diff --git a/src/ODSLF/ln_Smin_ME_ODSLF_XXZ.cc b/src/ODSLF/ln_Smin_ME_ODSLF_XXZ.cc index 746c7ef..66eb536 100644 --- a/src/ODSLF/ln_Smin_ME_ODSLF_XXZ.cc +++ b/src/ODSLF/ln_Smin_ME_ODSLF_XXZ.cc @@ -18,323 +18,317 @@ using namespace ABACUS; namespace ABACUS { -inline complex ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b) -{ - complex ans = 0.0; - complex prod_temp = 1.0; - int counter = 0; - int arg = 0; - int absarg = 0; - int par_comb_1, par_comb_2; + inline complex ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b) + { + complex ans = 0.0; + complex prod_temp = 1.0; + int counter = 0; + int arg = 0; + int absarg = 0; + int par_comb_1, par_comb_2; - for (int j = 0; j < B.chain.Nstrings; ++j) { + for (int j = 0; j < B.chain.Nstrings; ++j) { - par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0; - par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k]; + par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0; + par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k]; - for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { - for (int a = 1; a <= B.chain.Str_L[j]; ++a) { + for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { + for (int a = 1; a <= B.chain.Str_L[j]; ++a) { - if (!((j == k) && (alpha == beta) && (a == b))) { + if (!((j == k) && (alpha == beta) && (a == b))) { - arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); - 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])) ); - */ + arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); + absarg = abs(arg); - prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta]) - * (B.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2) - + II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) - * (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + B.chain.co_n_anis_over_2[absarg] * par_comb_2)); - } + prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] + - B.coshlambda[j][alpha] * B.sinhlambda[k][beta]) + * (B.chain.co_n_anis_over_2[absarg] * par_comb_1 + - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2) + + II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] + - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) + * (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + + B.chain.co_n_anis_over_2[absarg] * par_comb_2)); + } - if (counter++ > 100) { // we do at most 100 products before taking a log - ans += log(prod_temp); - prod_temp = 1.0; - counter = 0; - } + if (counter++ > 100) { // we do at most 100 products before taking a log + ans += log(prod_temp); + prod_temp = 1.0; + counter = 0; + } - }}} + }}} - return(ans + log(prod_temp)); -} - -inline complex ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b) -{ - complex ans = 0.0; - complex prod_temp = 1.0; - int counter = 0; - int arg = 0; - int absarg = 0; - int par_comb_1, par_comb_2; - - for (int j = 0; j < A.chain.Nstrings; ++j) { - - par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0; - par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k]; - - for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { - for (int a = 1; a <= A.chain.Str_L[j]; ++a) { - - arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); - absarg = abs(arg); - /* - prod_temp *= 0.5 * //done later... - ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) - * (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k]) - - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) - + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) - * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k]) - + A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) ); - */ - prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) - * (A.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2) - + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) - * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + A.chain.co_n_anis_over_2[absarg] * par_comb_2)); - - if (counter++ > 100) { // we do at most 100 products before taking a log - ans += log(prod_temp); - prod_temp = 1.0; - counter = 0; - } - }}} - - return(ans + log(prod_temp)); -} - -inline complex 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; - int absarg2 = abs(arg2); - - return(4.0/( - ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) - * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k]) - - sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) - + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) - * (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k]) - + A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) ) - * - ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) - * (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k]) - - sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) - + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) - * (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k]) - + A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) ) - )); - -} - -inline complex 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(-A.chain.par[j] + B.chain.par[k]))) - * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0)); -} - -complex 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."); - - // 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!"); - - // Compute the sinh and cosh of rapidities - - A.Compute_sinhlambda(); - A.Compute_coshlambda(); - B.Compute_sinhlambda(); - B.Compute_coshlambda(); - - // Some convenient arrays - - ODSLF_Lambda re_ln_Fn_F_B_0(B.chain, B.base); - ODSLF_Lambda im_ln_Fn_F_B_0(B.chain, B.base); - ODSLF_Lambda re_ln_Fn_G_0(B.chain, B.base); - ODSLF_Lambda im_ln_Fn_G_0(B.chain, B.base); - ODSLF_Lambda re_ln_Fn_G_2(B.chain, B.base); - ODSLF_Lambda im_ln_Fn_G_2(B.chain, B.base); - - complex ln_prod1 = 0.0; - complex ln_prod2 = 0.0; - complex ln_prod3 = 0.0; - complex ln_prod4 = 0.0; - - for (int i = 0; i < A.chain.Nstrings; ++i) - for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha) - for (int a = 1; a <= A.chain.Str_L[i]; ++a) - ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) - + 0.25 * II * PI * (1.0 - A.chain.par[i])))); - - for (int i = 0; i < B.chain.Nstrings; ++i) - for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha) - for (int a = 1; a <= B.chain.Str_L[i]; ++a) - if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) - + 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ) - ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) - + 0.25 * II * PI * (1.0 - B.chain.par[i])))); - - // Define the F ones earlier... - - for (int j = 0; j < B.chain.Nstrings; ++j) { - for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { - re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0)); - im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0)); - re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0)); - im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0)); - re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2)); - im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2)); - } + return(ans + log(prod_temp)); } - DP logabssinzeta = log(abs(sin(A.chain.anis))); + inline complex ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b) + { + complex ans = 0.0; + complex prod_temp = 1.0; + int counter = 0; + int arg = 0; + int absarg = 0; + int par_comb_1, par_comb_2; - // Define regularized products in prefactors + for (int j = 0; j < A.chain.Nstrings; ++j) { - for (int j = 0; j < A.chain.Nstrings; ++j) - for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) - for (int a = 1; a <= A.chain.Str_L[j]; ++a) - ln_prod3 += ln_Fn_F(A, j, alpha, a - 1); // assume only one-strings here + par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0; + par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k]; - ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis))); + for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { + for (int a = 1; a <= A.chain.Str_L[j]; ++a) { - for (int k = 0; k < B.chain.Nstrings; ++k) - for (int beta = 0; beta < B.base.Nrap[k]; ++beta) - for (int b = 1; b <= B.chain.Str_L[k]; ++b) { - if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta]; - else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1); + arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); + absarg = abs(arg); + prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] + - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) + * (A.chain.co_n_anis_over_2[absarg] * par_comb_1 + - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2) + + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] + - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) + * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + + A.chain.co_n_anis_over_2[absarg] * par_comb_2)); + + if (counter++ > 100) { // we do at most 100 products before taking a log + ans += log(prod_temp); + prod_temp = 1.0; + counter = 0; + } + }}} + + return(ans + log(prod_temp)); + } + + inline complex 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; + int absarg2 = abs(arg2); + + return(4.0/( + ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) + * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k]) + - sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) + + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) + * (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k]) + + A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) ) + * + ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) + * (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k]) + - sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) + + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) + * (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k]) + + A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) ) + )); + + } + + inline complex 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(-A.chain.par[j] + B.chain.par[k]))) + * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0)); + } + + complex 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."); + + // 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!"); + + // Compute the sinh and cosh of rapidities + + A.Compute_sinhlambda(); + A.Compute_coshlambda(); + B.Compute_sinhlambda(); + B.Compute_coshlambda(); + + // Some convenient arrays + + ODSLF_Lambda re_ln_Fn_F_B_0(B.chain, B.base); + ODSLF_Lambda im_ln_Fn_F_B_0(B.chain, B.base); + ODSLF_Lambda re_ln_Fn_G_0(B.chain, B.base); + ODSLF_Lambda im_ln_Fn_G_0(B.chain, B.base); + ODSLF_Lambda re_ln_Fn_G_2(B.chain, B.base); + ODSLF_Lambda im_ln_Fn_G_2(B.chain, B.base); + + complex ln_prod1 = 0.0; + complex ln_prod2 = 0.0; + complex ln_prod3 = 0.0; + complex ln_prod4 = 0.0; + + for (int i = 0; i < A.chain.Nstrings; ++i) + for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha) + for (int a = 1; a <= A.chain.Str_L[i]; ++a) + ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) + + 0.25 * II * PI * (1.0 - A.chain.par[i])))); + + for (int i = 0; i < B.chain.Nstrings; ++i) + for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha) + for (int a = 1; a <= B.chain.Str_L[i]; ++a) + if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) + + 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ) + ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) + + 0.25 * II * PI * (1.0 - B.chain.par[i])))); + + // Define the F ones earlier... + + for (int j = 0; j < B.chain.Nstrings; ++j) { + for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { + re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0)); + im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0)); + re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0)); + im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0)); + re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2)); + im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2)); + } } - ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis))); + DP logabssinzeta = log(abs(sin(A.chain.anis))); - // Now proceed to build the Hm matrix + // Define regularized products in prefactors - SQMat_CX Hm(0.0, A.base.Mdown); + for (int j = 0; j < A.chain.Nstrings; ++j) + for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) + for (int a = 1; a <= A.chain.Str_L[j]; ++a) + ln_prod3 += ln_Fn_F(A, j, alpha, a - 1); // assume only one-strings here - int index_a = 0; - int index_b = 0; + ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis))); - complex sum1 = 0.0; - complex sum2 = 0.0; - complex prod_num = 0.0; - complex Fn_K_0_G_0 = 0.0; - complex Prod_powerN = 0.0; - complex Fn_K_1_G_2 = 0.0; - complex one_over_A_sinhlambda_sq_plus_sinzetaover2sq; + for (int k = 0; k < B.chain.Nstrings; ++k) + for (int beta = 0; beta < B.base.Nrap[k]; ++beta) + for (int b = 1; b <= B.chain.Str_L[k]; ++b) { + if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta]; + else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1); + } + + ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis))); + + // Now proceed to build the Hm matrix + + SQMat_CX Hm(0.0, A.base.Mdown); + + int index_a = 0; + int index_b = 0; + + complex sum1 = 0.0; + complex sum2 = 0.0; + complex prod_num = 0.0; + complex Fn_K_0_G_0 = 0.0; + complex Prod_powerN = 0.0; + complex Fn_K_1_G_2 = 0.0; + complex one_over_A_sinhlambda_sq_plus_sinzetaover2sq; - for (int j = 0; j < A.chain.Nstrings; ++j) { - for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { - for (int a = 1; a <= A.chain.Str_L[j]; ++a) { + for (int j = 0; j < A.chain.Nstrings; ++j) { + for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { + for (int a = 1; a <= A.chain.Str_L[j]; ++a) { - index_b = 0; + index_b = 0; - one_over_A_sinhlambda_sq_plus_sinzetaover2sq = 1.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a) - + 0.25 * II * PI * (1.0 - A.chain.par[j]))) - * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a) - + 0.25 * II * PI * (1.0 - A.chain.par[j]))) - + pow(sin(0.5*A.chain.anis), 2.0)); + one_over_A_sinhlambda_sq_plus_sinzetaover2sq = + 1.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a) + + 0.25 * II * PI * (1.0 - A.chain.par[j]))) + * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a) + + 0.25 * II * PI * (1.0 - A.chain.par[j]))) + + pow(sin(0.5*A.chain.anis), 2.0)); - for (int k = 0; k < B.chain.Nstrings; ++k) { - for (int beta = 0; beta < B.base.Nrap[k]; ++beta) { - for (int b = 1; b <= B.chain.Str_L[k]; ++b) { + for (int k = 0; k < B.chain.Nstrings; ++k) { + for (int beta = 0; beta < B.base.Nrap[k]; ++beta) { + for (int b = 1; b <= B.chain.Str_L[k]; ++b) { - if (B.chain.Str_L[k] == 1) { + if (B.chain.Str_L[k] == 1) { - // use simplified code for one-string here: original form of Hm matrix + // use simplified code for one-string here: original form of Hm matrix - Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * - exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta); - Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) * - exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta); + Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * + exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta); + Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) * + exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta); - Prod_powerN = pow( B.chain.par[k] == 1 ? - (B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1]) - /(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1]) - : - (B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1]) - /(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1]) - , complex (B.chain.Nsites)); + Prod_powerN = pow( B.chain.par[k] == 1 ? + (B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1]) + /(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1]) + : + (B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1]) + /(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1]) + , complex (B.chain.Nsites)); - Hm[index_a][index_b] = Fn_K_0_G_0 - (1.0 - 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ - Prod_powerN * Fn_K_1_G_2; + Hm[index_a][index_b] = Fn_K_0_G_0 - (1.0 - 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ + Prod_powerN * Fn_K_1_G_2; - } // if (B.chain.Str_L == 1) + } // if (B.chain.Str_L == 1) - else { + else { - if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b); - else if (b == B.chain.Str_L[k]) { + if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b); + else if (b == B.chain.Str_L[k]) { - Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2); - for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i); + Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2); + for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i); - Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2); - for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i); + Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2); + for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i); - sum1 = 0.0; + sum1 = 0.0; - sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]); + sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) + * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]); - sum1 += (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]) - * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] - - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); + sum1 += (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]) + * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] + - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); - for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) + for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) - sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) * - exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]); + sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) * + exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]); - /* - sum2 = 0.0; + prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] + - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta); - for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]); + for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum) + prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinzeta); + // include all string contributions F_B_0 in this term - */ - prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta); + Hm[index_a][index_b] = prod_num * sum1; - for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum) - prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinzeta); - // include all string contributions F_B_0 in this term + } // else if (b == B.chain.Str_L[k]) + } // else - Hm[index_a][index_b] = prod_num * sum1; + index_b++; + }}} // sums over k, beta, b - } // else if (b == B.chain.Str_L[k]) - } // else + // now define the elements Hm[a][M] - index_b++; - }}} // sums over k, beta, b + Hm[index_a][B.base.Mdown] = one_over_A_sinhlambda_sq_plus_sinzetaover2sq; - // now define the elements Hm[a][M] + index_a++; + }}} // sums over j, alpha, a - Hm[index_a][B.base.Mdown] = one_over_A_sinhlambda_sq_plus_sinzetaover2sq; + complex ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4) + + 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinzeta - A.lnnorm - B.lnnorm; - index_a++; - }}} // sums over j, alpha, a + return(0.5 * ln_ME_sq); // Return ME, not MEsq - complex 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 diff --git a/src/ODSLF/ln_Sz_ME_ODSLF_XXZ.cc b/src/ODSLF/ln_Sz_ME_ODSLF_XXZ.cc index 6ccd7c9..6b87fa0 100644 --- a/src/ODSLF/ln_Sz_ME_ODSLF_XXZ.cc +++ b/src/ODSLF/ln_Sz_ME_ODSLF_XXZ.cc @@ -18,327 +18,324 @@ using namespace ABACUS; namespace ABACUS { -inline complex ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b) -{ - complex ans = 0.0; - complex prod_temp = 1.0; - int counter = 0; - int arg = 0; - int absarg = 0; - int par_comb_1, par_comb_2; + inline complex ln_Fn_F (ODSLF_XXZ_Bethe_State& B, int k, int beta, int b) + { + complex ans = 0.0; + complex prod_temp = 1.0; + int counter = 0; + int arg = 0; + int absarg = 0; + int par_comb_1, par_comb_2; - for (int j = 0; j < B.chain.Nstrings; ++j) { + for (int j = 0; j < B.chain.Nstrings; ++j) { - par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0; - par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k]; + par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0; + par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k]; - for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { + for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { - for (int a = 1; a <= B.chain.Str_L[j]; ++a) { + for (int a = 1; a <= B.chain.Str_L[j]; ++a) { - if (!((j == k) && (alpha == beta) && (a == b))) { + if (!((j == k) && (alpha == beta) && (a == b))) { - arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); - 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)); + arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); + absarg = abs(arg); + prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] + - B.coshlambda[j][alpha] * B.sinhlambda[k][beta]) + * (B.chain.co_n_anis_over_2[absarg] * par_comb_1 + - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2) + + II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] + - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) + * (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + + B.chain.co_n_anis_over_2[absarg] * par_comb_2)); - } + } - if (counter++ > 100) { // we do at most 100 products before taking a log - ans += log(prod_temp); - prod_temp = 1.0; - counter = 0; - } + if (counter++ > 100) { // we do at most 100 products before taking a log + ans += log(prod_temp); + prod_temp = 1.0; + counter = 0; + } - }}} + }}} - return(ans + log(prod_temp)); -} - -inline complex ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b) -{ - complex ans = 0.0; - complex prod_temp = 1.0; - int counter = 0; - int arg = 0; - int absarg = 0; - int par_comb_1, par_comb_2; - - for (int j = 0; j < A.chain.Nstrings; ++j) { - - par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0; - par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k]; - - for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { - - for (int a = 1; a <= A.chain.Str_L[j]; ++a) { - - arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); - absarg = abs(arg); - - /* - prod_temp *= 0.5 * - ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) - * (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k]) - - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) - + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) - * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k]) - + A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) ); - */ - prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) - * (A.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2) - + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) - * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + A.chain.co_n_anis_over_2[absarg] * par_comb_2)); - - if (counter++ > 100) { // we do at most 100 products before taking a log - ans += log(prod_temp); - prod_temp = 1.0; - counter = 0; - } - }}} - - return(ans + log(prod_temp)); -} - -inline complex 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; - int absarg2 = abs(arg2); - - return(4.0/( - ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) - * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k]) - - sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) - + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) - * (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k]) - + A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) ) - * - ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) - * (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k]) - - sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) - + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) - * (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k]) - + A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) ) - )); - -} - -inline complex 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(-A.chain.par[j] + B.chain.par[k]))) - * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0)); -} - -complex 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."); - - // 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!"); - - // Compute the sinh and cosh of rapidities - - A.Compute_sinhlambda(); - A.Compute_coshlambda(); - B.Compute_sinhlambda(); - B.Compute_coshlambda(); - - // Some convenient arrays - - ODSLF_Lambda re_ln_Fn_F_B_0(B.chain, B.base); - ODSLF_Lambda im_ln_Fn_F_B_0(B.chain, B.base); - ODSLF_Lambda re_ln_Fn_G_0(B.chain, B.base); - ODSLF_Lambda im_ln_Fn_G_0(B.chain, B.base); - ODSLF_Lambda re_ln_Fn_G_2(B.chain, B.base); - ODSLF_Lambda im_ln_Fn_G_2(B.chain, B.base); - - complex ln_prod1 = 0.0; - complex ln_prod2 = 0.0; - complex ln_prod3 = 0.0; - complex ln_prod4 = 0.0; - - for (int i = 0; i < A.chain.Nstrings; ++i) - for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha) - for (int a = 1; a <= A.chain.Str_L[i]; ++a) - ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) - + 0.25 * II * PI * (1.0 - A.chain.par[i])))); - - for (int i = 0; i < B.chain.Nstrings; ++i) - for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha) - for (int a = 1; a <= B.chain.Str_L[i]; ++a) - if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) - + 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ) - ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) - + 0.25 * II * PI * (1.0 - B.chain.par[i])))); - - // Define the F ones earlier... - - for (int j = 0; j < B.chain.Nstrings; ++j) { - for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { - re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0)); - im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0)); - re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0)); - im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0)); - re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2)); - im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2)); - } + return(ans + log(prod_temp)); } - DP logabssinzeta = log(abs(sin(A.chain.anis))); + inline complex ln_Fn_G (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B, int k, int beta, int b) + { + complex ans = 0.0; + complex prod_temp = 1.0; + int counter = 0; + int arg = 0; + int absarg = 0; + int par_comb_1, par_comb_2; - // Define regularized products in prefactors + for (int j = 0; j < A.chain.Nstrings; ++j) { - for (int j = 0; j < A.chain.Nstrings; ++j) - for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) - for (int a = 1; a <= A.chain.Str_L[j]; ++a) { - ln_prod3 += ln_Fn_F (A, j, alpha, a - 1); + par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0; + par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k]; + + for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { + + for (int a = 1; a <= A.chain.Str_L[j]; ++a) { + + arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b); + absarg = abs(arg); + + prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] + - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) + * (A.chain.co_n_anis_over_2[absarg] * par_comb_1 + - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2) + + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] + - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) + * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + + A.chain.co_n_anis_over_2[absarg] * par_comb_2)); + + if (counter++ > 100) { // we do at most 100 products before taking a log + ans += log(prod_temp); + prod_temp = 1.0; + counter = 0; + } + }}} + + return(ans + log(prod_temp)); + } + + inline complex 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; + int absarg2 = abs(arg2); + + return(4.0/( + ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) + * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k]) + - sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) + + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) + * (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k]) + + A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) ) + * + ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) + * (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k]) + - sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) + + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) + * (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k]) + + A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) ) + )); + + } + + inline complex 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(-A.chain.par[j] + B.chain.par[k]))) + * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0)); + } + + complex 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."); + + // 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!"); + + // Compute the sinh and cosh of rapidities + + A.Compute_sinhlambda(); + A.Compute_coshlambda(); + B.Compute_sinhlambda(); + B.Compute_coshlambda(); + + // Some convenient arrays + + ODSLF_Lambda re_ln_Fn_F_B_0(B.chain, B.base); + ODSLF_Lambda im_ln_Fn_F_B_0(B.chain, B.base); + ODSLF_Lambda re_ln_Fn_G_0(B.chain, B.base); + ODSLF_Lambda im_ln_Fn_G_0(B.chain, B.base); + ODSLF_Lambda re_ln_Fn_G_2(B.chain, B.base); + ODSLF_Lambda im_ln_Fn_G_2(B.chain, B.base); + + complex ln_prod1 = 0.0; + complex ln_prod2 = 0.0; + complex ln_prod3 = 0.0; + complex ln_prod4 = 0.0; + + for (int i = 0; i < A.chain.Nstrings; ++i) + for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha) + for (int a = 1; a <= A.chain.Str_L[i]; ++a) + ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) + + 0.25 * II * PI * (1.0 - A.chain.par[i])))); + + for (int i = 0; i < B.chain.Nstrings; ++i) + for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha) + for (int a = 1; a <= B.chain.Str_L[i]; ++a) + if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) + + 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ) + ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0) + + 0.25 * II * PI * (1.0 - B.chain.par[i])))); + + // Define the F ones earlier... + + for (int j = 0; j < B.chain.Nstrings; ++j) { + for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) { + re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0)); + im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0)); + re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0)); + im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0)); + re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2)); + im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2)); } + } - ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis))); + DP logabssinzeta = log(abs(sin(A.chain.anis))); - for (int k = 0; k < B.chain.Nstrings; ++k) - for (int beta = 0; beta < B.base.Nrap[k]; ++beta) - for (int b = 1; b <= B.chain.Str_L[k]; ++b) { - if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta]; - else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1); - } + // Define regularized products in prefactors - ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis))); + for (int j = 0; j < A.chain.Nstrings; ++j) + for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) + for (int a = 1; a <= A.chain.Str_L[j]; ++a) { + ln_prod3 += ln_Fn_F (A, j, alpha, a - 1); + } - // Now proceed to build the Hm2P matrix + ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis))); - SQMat_CX Hm2P(0.0, A.base.Mdown); + for (int k = 0; k < B.chain.Nstrings; ++k) + for (int beta = 0; beta < B.base.Nrap[k]; ++beta) + for (int b = 1; b <= B.chain.Str_L[k]; ++b) { + if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta]; + else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1); + } - int index_a = 0; - int index_b = 0; + ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis))); - complex sum1 = 0.0; - complex sum2 = 0.0; - complex prod_num = 0.0; - complex Fn_K_0_G_0 = 0.0; - complex Prod_powerN = 0.0; - complex Fn_K_1_G_2 = 0.0; - complex two_over_A_sinhlambda_sq_plus_sinzetaover2sq; + // Now proceed to build the Hm2P matrix + + SQMat_CX Hm2P(0.0, A.base.Mdown); + + int index_a = 0; + int index_b = 0; + + complex sum1 = 0.0; + complex sum2 = 0.0; + complex prod_num = 0.0; + complex Fn_K_0_G_0 = 0.0; + complex Prod_powerN = 0.0; + complex Fn_K_1_G_2 = 0.0; + complex two_over_A_sinhlambda_sq_plus_sinzetaover2sq; - for (int j = 0; j < A.chain.Nstrings; ++j) { - for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { - for (int a = 1; a <= A.chain.Str_L[j]; ++a) { + for (int j = 0; j < A.chain.Nstrings; ++j) { + for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) { + for (int a = 1; a <= A.chain.Str_L[j]; ++a) { - index_b = 0; + index_b = 0; - two_over_A_sinhlambda_sq_plus_sinzetaover2sq = 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a) - + 0.25 * II * PI * (1.0 - A.chain.par[j]))) - * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a) - + 0.25 * II * PI * (1.0 - A.chain.par[j]))) - + pow(sin(0.5*A.chain.anis), 2.0)); + two_over_A_sinhlambda_sq_plus_sinzetaover2sq = + 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a) + + 0.25 * II * PI * (1.0 - A.chain.par[j]))) + * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a) + + 0.25 * II * PI * (1.0 - A.chain.par[j]))) + + pow(sin(0.5*A.chain.anis), 2.0)); - for (int k = 0; k < B.chain.Nstrings; ++k) { - for (int beta = 0; beta < B.base.Nrap[k]; ++beta) { - for (int b = 1; b <= B.chain.Str_L[k]; ++b) { + for (int k = 0; k < B.chain.Nstrings; ++k) { + for (int beta = 0; beta < B.base.Nrap[k]; ++beta) { + for (int b = 1; b <= B.chain.Str_L[k]; ++b) { - if (B.chain.Str_L[k] == 1) { + if (B.chain.Str_L[k] == 1) { - // use simplified code for one-string here: original form of Hm2P matrix + // use simplified code for one-string here: original form of Hm2P matrix - Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * - exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta); - Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) * - exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta); + Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * + exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta); + Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) * + exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta); - Prod_powerN = pow( B.chain.par[k] == 1 ? - (B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1]) - /(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1]) - : - (B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1]) - /(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1]) - , complex (B.chain.Nsites)); + Prod_powerN = pow( B.chain.par[k] == 1 ? + (B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1]) + /(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1]) + : + (B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1]) + /(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1]) + , complex (B.chain.Nsites)); - Hm2P[index_a][index_b] = Fn_K_0_G_0 - (-1.0 + 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ - Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq + Hm2P[index_a][index_b] = Fn_K_0_G_0 - (-1.0 + 2.0 * (B.base.Mdown % 2)) * // MODIF from XXZ + Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinzeta); - } + } - else { + else { - if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b); - else if (b == B.chain.Str_L[k]) { + if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b); + else if (b == B.chain.Str_L[k]) { - Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2); - for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i); + Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2); + for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i); - Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2); - for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i); + Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2); + for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i); - sum1 = 0.0; + sum1 = 0.0; - sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]); + sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) + * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]); - sum1 += (-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]) - * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] - - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); + sum1 += (-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]) + * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] + - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); - for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) + for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) - sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) * - exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]); + sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) * + exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]); - sum2 = 0.0; + 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); - // include all string contributions F_B_0 in this term + for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum) + prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logabssinzeta); + // include all string contributions F_B_0 in this term - Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinhlambda_sq_plus_sinzetaover2sq); + Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinhlambda_sq_plus_sinzetaover2sq); - } // else if (b == B.chain.Str_L[k]) - } // else + } // else if (b == B.chain.Str_L[k]) + } // else - index_b++; - }}} // sums over k, beta, b - index_a++; - }}} // sums over j, alpha, a + index_b++; + }}} // sums over k, beta, b + index_a++; + }}} // sums over j, alpha, a - DP re_ln_det = real(lndet_LU_CX_dstry(Hm2P)); + DP re_ln_det = real(lndet_LU_CX_dstry(Hm2P)); - complex 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; + complex ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4) + + 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(0.5 * ln_ME_sq); // Return ME, not MEsq - //return(ln_ME_sq); - return(0.5 * ln_ME_sq); // Return ME, not MEsq - -} + } } // namespace ABACUS diff --git a/src/RICHARDSON/Richardson.cc b/src/RICHARDSON/Richardson.cc index b39d095..79fa15b 100644 --- a/src/RICHARDSON/Richardson.cc +++ b/src/RICHARDSON/Richardson.cc @@ -31,21 +31,20 @@ namespace ABACUS { //DP bquad = -1.0/g_int - sumoneovereps[j]; //DP cquad = sumSovereps[j]; /* - DP discr = 0.0; - bool retval = false; - //if ((discr = bquad * bquad - 4.0 * cquad) >= 0.0) { - if ((discr = (1.0/g_int + sumoneovereps[j]) * (1.0/g_int + sumoneovereps[j]) - 4.0 * sumSovereps[j]) >= 0.0) { + DP discr = 0.0; + bool retval = false; + //if ((discr = bquad * bquad - 4.0 * cquad) >= 0.0) { + if ((discr = (1.0/g_int + sumoneovereps[j]) * (1.0/g_int + sumoneovereps[j]) - 4.0 * sumSovereps[j]) >= 0.0) { discr = sqrt(discr); Sjleft = 0.5 * (-(1.0/g_int + sumoneovereps[j]) - discr); Sjright = 0.5 * (-(1.0/g_int + sumoneovereps[j]) + discr); retval = true; - } + } - return(retval); + return(retval); */ complex discr = sqrt((1.0/g_int + sumoneovereps[j]) * (1.0/g_int + sumoneovereps[j]) - 4.0 * sumSovereps[j]); - //complex 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