Import ABACUS++G_8 code; cleanup files; new README

This commit is contained in:
J.-S. Caux
2018-02-09 17:34:05 +01:00
parent 61084ef3b3
commit 103cbe84d6
172 changed files with 46745 additions and 0 deletions
+122
View File
@@ -0,0 +1,122 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC.h
Purpose: Core header file, includes all descendents.
***********************************************************/
#ifndef _JSC_H_
#define _JSC_H_
// This core header file includes all the others
const char JSC_VERSION[20] = "ABACUS++G_8";
// Standard includes
#include <cmath>
#include <complex> // for complex number algebra
#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib> // for exit(), ...
#include <ctime> // for clock(), ...
#include <limits> // for numeric limits
#include <climits> // for numeric limits
// For file sizes, etc
#include "sys/types.h"
#include "sys/stat.h"
#include "unistd.h"
// Signal handling
#include <stdio.h> /* standard I/O functions */
#include <unistd.h> /* standard unix functions, like getpid() */
#include <sys/types.h> /* various type definitions, like pid_t */
#include <signal.h> /* signal name macros, and the signal() prototype */
// My own math functions and shortcuts
#include "JSC_util.h"
// Vectors and matrices
#include "JSC_Vect.h" // My vector class definitions
#include "JSC_Matrix.h" // My matrix class definitions
// Choose_Table
#include "JSC_Combi.h"
// Fitting, interpolating
#include "JSC_Fitting.h"
// Young tableaux
#include "JSC_Young.h"
// Integration
#include "JSC_Integ.h"
// Special functions:
#include "JSC_Spec_Fns.h"
//*** Integrable models:
// Heisenberg spin-1/2 antiferromagnet
#include "JSC_Heis.h"
// Lieb-Liniger
#include "JSC_LiebLin.h"
// One-d spinless fermions:
#include "JSC_ODSLF.h"
// General:
//#include "JSC_Bethe.h"
// Thermodynamic Bethe Ansatz utilities
#include "JSC_TBA.h"
// State ensembles
#include "JSC_State_Ensemble.h"
// XXX in zero field: Uq(sl(2)) stuff
#include "JSC_XXX_h0.h"
// XXZ in zero field: quantum groups
#include "JSC_XXZ_h0.h"
// Two-component Bose gas
//#include "2CBG.h"
// Richardson
//#include "Richardson.h"
// *** Correlation functions:
// New scanning protocols for ABACUS++
#include "JSC_Scan.h"
// Functions for everybody
//#include "JSC_fns.h" // KEEP THIS INCLUDE LAST, SINCE IT USES PREVIOUS DECLARATIONS
// Numerical RG:
#include "JSC_NRG.h"
// OpenMP
#include <omp.h>
// Typedefs:
typedef double DP;
#endif // _JSC_H_
+109
View File
@@ -0,0 +1,109 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_Bethe.h
Purpose: Declares Bethe state-related classes and functions.
***********************************************************/
#ifndef _BETHE_
#define _BETHE_
#include "JSC.h"
namespace JSC {
/*
class Model {
protected:
string Name; // LiebLin, XXZ, XXX, XXZ_gpd
int Nsites; //
int L;
DP interaction;
public:
Model (string Name_ref,
};
*/
class Base {
public:
int charge; // charge of the base: number of particles (LiebLin gas), number of down spins (Heis), ...
Vect<int> Nrap; // Nrap[i] contains the number of rapidities of type i, i = 0, ..., Nstrings - 1.
int Nraptot; // total number of strings in this state
Vect<DP> Ix2_infty; // Ix2_infty[i] contains the max of BAE function for the (half-)integer I[i], i = 0, Nstrings - 1.
Vect<int> Ix2_min;
Vect<int> Ix2_max; // Ix2_max[i] contains the integer part of 2*I_infty, with correct parity for base.
string baselabel;
public:
Base ();
Base (const Base& RefBase); // copy constructor
public: // LiebLin constructors
Base (int N); // Constructor for repulsive LiebLin gas case: one type of particle
public: // HEIS constructors
//Base (const Heis_Chain& RefChain, int M); // constructs configuration with all Mdown in one-string of +1 parity // DEPRECATED
Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities); // sets to Nrapidities vector, and checks consistency
Base (const Heis_Chain& RefChain, string baselabel_ref);
public: // operators
Base& operator= (const Base& RefBase);
bool operator== (const Base& RefBase);
bool operator!= (const Base& RefBase);
public: // member functions
void Compute_Ix2_limits(const Heis_Chain& RefChain); // computes the Ix2_infty and Ix2_max
};
//****************************************************************************
// Class Bethe_State is a wrapper class for all types of eigenstates
class Bethe_State {
public: // configuration
Base base;
Vect<Vect<int> > Ix2;
Vect<Vect<DP> > lambda;
public: // properties
DP E;
int iK;
DP K;
DP lnnorm;
public: // identification
string label; // this is the relative label by default
Vect<Vect<int> > OriginIx2; // to define the relative label
public: // convergence
DP diffsq;
int conv;
int iter;
int iter_Newton;
//public: // for descendents, etc
public: // constructors
Bethe_State();
Bethe_State (const Bethe_State& RefState); // copy constructor
Bethe_State (const Bethe_State& OriginState, string label_ref);
LiebLin_Bethe_State& operator= (const LiebLin_Bethe_State& RefState);
} // namespace JSC
#endif
+51
View File
@@ -0,0 +1,51 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS++ library.
Copyright (c) 2006-9.
-----------------------------------------------------------
File: JSC_Combi.h
Purpose: Declares combinatorics-related classes and functions.
Last modified: 08/10/2009
***********************************************************/
#ifndef _COMBI_
#define _COMBI_
#include "JSC.h"
namespace JSC {
//***********************************************************************
class Choose_Table {
private:
int Npower;
int Npowerp1;
int dim;
unsigned long long int* table;
void Fill_table ();
public:
Choose_Table ();
Choose_Table (int Npower_ref);
Choose_Table (const Choose_Table& Ref_Choose_Table); // constructs a new object from an existing one
int power(); // returns Npower
unsigned long long int choose (int N, int M);
~Choose_Table ();
};
std::ostream& operator<< (std::ostream& s, Choose_Table& Ref_table);
} // namespace JSC
#endif
+37
View File
@@ -0,0 +1,37 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC.h
Purpose: Core header file, includes all descendents.
***********************************************************/
#ifndef _FITTING_
#define _FITTING_
namespace JSC {
// Functions in src/FITTING directory
void covsrt (SQMat_DP& covar, Vect<bool>& ia, const int mfit);
void lin_reg (Vect_DP x, Vect_DP y, Vect_DP sigma, DP& a, DP& b, DP& chisq);
void lin_reg (Vect_DP x, Vect_DP y, DP& a, DP& b, DP& chisq);
void mrqmin (Vect_DP& x, Vect_DP& y, Vect_DP& sig, Vect_DP& a,
Vect<bool>& ia, SQMat_DP& covar, SQMat_DP& alpha, DP& chisq,
void funcs(const DP, Vect_DP&, DP&, Vect_DP&), DP& alambda);
void mrqcof (Vect_DP& x, Vect_DP& y, Vect_DP& sig, Vect_DP& a,
Vect<bool>& ia, SQMat_DP& alpha, Vect_DP& beta, DP& chisq,
void funcs (const DP, Vect_DP&, DP&, Vect_DP&));
// For interpolating:
void polint(Vect_DP& xa, Vect_DP& ya, const DP x, DP& y, DP& dy);
void polint(Vect_CX& xa, Vect_CX& ya, const complex<DP> x, complex<DP>& y, complex<DP>& dy);
} // namespace JSC
#endif
+777
View File
@@ -0,0 +1,777 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS++ library.
Copyright (c)
-----------------------------------------------------------
File: Heis.h
Purpose: Declares Heisenberg chain classes and functions.
***********************************************************/
#ifndef _HEIS_
#define _HEIS_
#include "JSC.h"
namespace JSC {
// First, some global constants...
const long long int ID_UPPER_LIMIT = 10000000LL; // max size of vectors we can define without seg fault
const int INTERVALS_SIZE = 100000; // size of Scan_Intervals arrays
const int NBASESMAX = 1000; // max number of bases kept
const DP ITER_REQ_PREC = 100.0 * MACHINE_EPS_SQ;
//const DP ITER_REQ_PREC = MACHINE_EPS_SQ;
// Cutoffs on particle numbers
//const int NPARTICLES_MAX = 24;
//const int NHOLES_MAX = NPARTICLES_MAX/2;
//const int MAX_RAPS_ABOVE_ZERO = 10; // max nr of rapidities above lowest type
//const int NPARTICLES_MAX = 2;
//const int NHOLES_MAX = 1;
//const int MAX_TYPES_IN_BASE = 4; // maximal number of particle types we allow in bases
const int MAXSTRINGS = 20; // maximal number of particle types we allow in bases
//const int MAXSTRINGS = 2; // maximal number of particle types we allow in bases
//const DP HEIS_deltaprec = 1.0e-6;//1.0e-4; // maximal string deviation allowed // DEPRECATED in ++T_9
const int NEXC_MAX_HEIS = 16; // maximal number of excitations (string binding/unbinding, particle-hole) considered
//***********************************************************************
class Heis_Chain {
public:
DP J;
DP Delta;
DP anis; // acos(Delta) if Delta < 1.0, 0 if Delta == 1.0, acosh(Delta) if Delta > 1.0
DP hz;
int Nsites;
int Nstrings; // how many possible strings. The following two arrays have Nstrings nonzero elements.
int* Str_L; // vector (length M) containing the allowed string lengths. Elements that are 0 have no meaning.
int* par; // vector (length M) containing the parities of the strings. Elements that are 0 have no meaning.
// Parities are all +1 except for gapless XXZ subcases
DP* si_n_anis_over_2; // for optimization: sin for XXZ, sinh for XXZ_gpd
DP* co_n_anis_over_2; // for optimization
DP* ta_n_anis_over_2; // for optimization
DP prec; // precision required for computations, always put to ITER_REQ_PREC
public:
Heis_Chain ();
Heis_Chain (DP JJ, DP DD, DP hh, int NN); // contructor: simply initializes
Heis_Chain (const Heis_Chain& RefChain); // copy constructor;
Heis_Chain& operator= (const Heis_Chain& RefChain);
bool operator== (const Heis_Chain& RefChain);
bool operator!= (const Heis_Chain& RefChain);
~Heis_Chain(); // destructor
public:
//void Scan_for_Possible_Bases (int Mdown, Vect<long long int>& possible_base_id, int& nfound, int nexc_max_used,
// int base_level_to_scan, Vect<int>& Nrapidities);
//Vect<long long int> Possible_Bases (int Mdown); // returns a vector of possible bases
/* Deactivated in ++G_8
void Scan_for_Possible_Bases (int Mdown, Vect<string>& possible_base_label, int& nfound, int nexc_max_used,
int base_level_to_scan, Vect<int>& Nrapidities);
Vect<string> Possible_Bases (int Mdown); // returns a vector of possible bases
*/
};
//****************************************************************************
// Objects in class Heis_Base are a checked vector containing the number of rapidities of allowable types for a given state
class Heis_Base {
public:
int Mdown; // total number of down spins
Vect<int> Nrap; // Nrap[i] contains the number of rapidities of type i, i = 0, Nstrings - 1.
int Nraptot; // total number of strings in this state
Vect<DP> Ix2_infty; // Ix2_infty[i] contains the max of BAE function for the (half-)integer I[i], i = 0, Nstrings - 1.
Vect<int> Ix2_min;
Vect<int> Ix2_max; // Ix2_max[i] contains the integer part of 2*I_infty, with correct parity for base.
//long long int id; // identification number
double dimH; // dimension of sub Hilbert space associated to this base; use double to avoid max int problems.
string baselabel; // base label
public:
Heis_Base ();
Heis_Base (const Heis_Base& RefBase); // copy constructor
Heis_Base (const Heis_Chain& RefChain, int M); // constructs configuration with all Mdown in one-string of +1 parity
Heis_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities); // sets to Nrapidities vector, and checks consistency
//Heis_Base (const Heis_Chain& RefChain, long long int id_ref);
Heis_Base (const Heis_Chain& RefChain, string baselabel_ref);
inline int& operator[] (const int i);
inline const int& operator[] (const int i) const;
Heis_Base& operator= (const Heis_Base& RefBase);
bool operator== (const Heis_Base& RefBase);
bool operator!= (const Heis_Base& RefBase);
void Compute_Ix2_limits(const Heis_Chain& RefChain); // computes the Ix2_infty and Ix2_max
//void Scan_for_Possible_Types (Vect<long long int>& possible_type_id, int& nfound, int base_level, Vect<int>& Nexcitations);
//Vect<long long int> Possible_Types (); // returns a vector of possible types
};
inline int& Heis_Base::operator[] (const int i)
{
return Nrap[i];
}
inline const int& Heis_Base::operator[] (const int i) const
{
return Nrap[i];
}
//****************************************************************************
/*
// Objects in class Ix2_Config carry all the I's of a given state
class Ix2_Config {
//private:
public:
int Nstrings;
Vect<int> Nrap;
int Nraptot;
//int** Ix2;
Vect<Vect<int> > Ix2;
public:
Ix2_Config ();
Ix2_Config (const Heis_Chain& RefChain, int M); // constructor, puts I's to ground state
Ix2_Config (const Heis_Chain& RefChain, const Heis_Base& base); // constructor, putting I's to lowest-energy config
// consistent with Heis_Base configuration for chain RefChain
Ix2_Config& operator= (const Ix2_Config& RefConfig);
//inline int* operator[] (const int i);
inline Vect<int> operator[] (const int i);
//inline const int* operator[] (const int i) const;
inline const Vect<int> operator[] (const int i) const;
//~Ix2_Config(); // not needed, inherited from Vect
string Return_Label (const Ix2_Config& OriginIx2);
};
//inline int* Ix2_Config::operator[] (const int i)
inline Vect<int> Ix2_Config::operator[] (const int i)
{
return Ix2[i];
}
//inline const int* Ix2_Config::operator[] (const int i) const
inline const Vect<int> Ix2_Config::operator[] (const int i) const
{
return Ix2[i];
}
std::ostream& operator<< (std::ostream& s, const Ix2_Config& RefConfig);
*/
//****************************************************************************
// Objects in class Lambda carry all rapidities of a state
class Lambda {
private:
int Nstrings;
Vect<int> Nrap;
int Nraptot;
DP** lambda;
//Vect<Vect<DP> > lambda;
public:
Lambda ();
Lambda (const Heis_Chain& RefChain, int M); // constructor, puts all lambda's to zero
Lambda (const Heis_Chain& RefChain, const Heis_Base& base); // constructor, putting I's to lowest-energy config
// consistent with Heis_Base configuration for chain RefChain
Lambda& operator= (const Lambda& RefConfig);
inline DP* operator[] (const int i);
//inline Vect<DP> operator[] (const int i);
inline const DP* operator[] (const int i) const;
//inline const Vect<DP> operator[] (const int i) const;
~Lambda();
};
inline DP* Lambda::operator[] (const int i)
//inline Vect<DP> Lambda::operator[] (const int i)
{
return lambda[i];
}
inline const DP* Lambda::operator[] (const int i) const
//inline const Vect<DP> Lambda::operator[] (const int i) const
{
return lambda[i];
}
//****************************************************************************
// Objects in class Ix2_Offsets carry Young tableau representations of the Ix2 configurations
/*
class Ix2_Offsets {
public:
Heis_Base base;
Vect<Young_Tableau> Tableau; // vector of pointers to tableaux at each level
long long int type_id;
long long int id; // id number of offset
long long int maxid; // max id number allowable
public:
Ix2_Offsets ();
Ix2_Offsets (const Ix2_Offsets& RefOffset); // copy constructor
Ix2_Offsets (const Heis_Base& RefBase, long long int req_type_id);
Ix2_Offsets (const Heis_Base& RefBase, Vect<int> nparticles); // sets all tableaux to empty ones, with nparticles[] at each level
Ix2_Offsets& operator= (const Ix2_Offsets& RefOffset);
bool operator<= (const Ix2_Offsets& RefOffsets);
bool operator>= (const Ix2_Offsets& RefOffsets);
public:
void Set_to_id (long long int idnr);
void Compute_id ();
void Compute_type_id ();
public:
bool Add_Boxes_From_Lowest (int Nboxes, bool odd_sectors); // adds Nboxes in minimal energy config, all boxes in either even or odd sectors
};
inline long long int Ix2_Offsets_type_id (Vect<int>& nparticles)
{
long long int type_id_here = 0ULL;
for (int i = 0; i < nparticles.size(); ++i)
type_id_here += nparticles[i] * pow_ulli(10ULL, i);
return(type_id_here);
}
long long int Find_idmin (Ix2_Offsets& scan_offsets, int particle_type, int tableau_level, int Row_L_min);
long long int Find_idmax (Ix2_Offsets& scan_offsets, int particle_type, int tableau_level);
*/
//****************************************************************************
// Objects in class Ix2_Offsets_List carry a vector of used Ix2_Offsets
/*
class Ix2_Offsets_List {
public:
int ndef;
Vect<Ix2_Offsets> Offsets;
public:
Ix2_Offsets_List ();
Ix2_Offsets& Return_Offsets (Heis_Base& RefBase, Vect<int> nparticles); // returns the Ix2_Offsets corresponding to nparticles[]/base
Ix2_Offsets& Return_Offsets (Heis_Base& RefBase, long long int req_type_id);
};
*/
//****************************************************************************
// Objects in class Heis_Bethe_State carry all information about an eigenstate
// Derived classes include XXZ_Bethe_State, XXX_Bethe_State, XXZ_gpd_Bethe_State
// These contain subclass-specific functions and data.
class Heis_Bethe_State {
public:
Heis_Chain chain;
Heis_Base base;
//Ix2_Offsets offsets;
//Ix2_Config Ix2;
Vect<Vect<int> > Ix2;
Lambda lambda;
Lambda deviation; // string deviations
Lambda BE; // Bethe equation for relevant rapidity, in the form BE = theta - (1/N)\sum ... - \pi I/N = 0
DP diffsq; // sum of squares of rapidity differences in last iteration
int conv; // convergence status
DP dev; // sum of absolute values of string deviations
int iter; // number of iterations necessary for convergence
int iter_Newton; // number of iterations necessary for convergence (Newton method)
DP E; // total energy
int iK; // K = 2.0*PI * iK/Nsites
DP K; // total momentum
DP lnnorm; // ln of norm of reduced Gaudin matrix
//long long int base_id;
//long long int type_id;
//long long int id;
//long long int maxid;
//int nparticles;
string label;
public:
Heis_Bethe_State ();
Heis_Bethe_State (const Heis_Bethe_State& RefState); // copy constructor
//Heis_Bethe_State (const Heis_Bethe_State& RefState, long long int type_id_ref); // new state with requested type_id
Heis_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
Heis_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base); // constructor to lowest-energy config with base
//Heis_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref);
virtual ~Heis_Bethe_State () {};
public:
int Charge () { return(base.Mdown); };
//void Set_Ix2_Offsets (const Ix2_Offsets& RefOffset); // sets the Ix2 to given offsets
//void Set_to_id (long long int id_ref);
//void Set_to_id (long long int id_ref, Heis_Bethe_State& RefState);
//int Nparticles (); // counts the number of particles in state once Ix2 offsets set (so type_id is correctly set)
//void Set_to_Label (string label_ref, const Ix2_Config& OriginIx2);
void Set_to_Label (string label_ref, const Vect<Vect<int> >& OriginIx2);
void Set_Label_from_Ix2 (const Vect<Vect<int> >& OriginIx2);
bool Check_Symmetry (); // checks whether the I's are symmetrically distributed
void Compute_diffsq (); // \sum BE[j][alpha]^2
void Find_Rapidities (bool reset_rapidities); // Finds the rapidities
void Find_Rapidities_Twisted (bool reset_rapidities, DP twist); // Finds the rapidities with twist added to RHS of logBE
//void BAE_smackdown (DP max_allowed);
//void Solve_BAE_smackdown (DP max_allowed, int maxruns);
void Solve_BAE_bisect (int j, int alpha, DP req_prec, int itermax);
void Iterate_BAE (DP iter_factor); // Finds new set of lambda[j][alpha] from previous one by simple iteration
void Solve_BAE_straight_iter (DP straight_prec, int max_iter_interp, DP iter_factor);
void Solve_BAE_extrap (DP extrap_prec, int max_iter_extrap, DP iter_factor);
void Iterate_BAE_Newton (); // Finds new set of lambda[j][alpha] from previous one by a Newton step
void Solve_BAE_Newton (DP Newton_prec, int max_iter_Newton);
void Solve_BAE_with_silk_gloves (DP silk_prec, int max_iter_silk, DP iter_factor);
void Compute_lnnorm ();
void Compute_Momentum ();
void Compute_All (bool reset_rapidities); // solves BAE, computes E, K and lnnorm
inline bool Set_to_Inner_Skeleton (int iKneeded, const Vect<Vect<int> >& OriginStateIx2)
{
Ix2[0][0] = Ix2[0][1] - 2;
Ix2[0][base.Nrap[0] - 1] = Ix2[0][base.Nrap[0] - 2] + 2;
(*this).Compute_Momentum();
if (base.Nrap[0] == 0) return(false);
if (iKneeded >= iK) Ix2[0][base.Nrap[0]-1] += 2*(iKneeded - iK);
else Ix2[0][0] += 2*(iKneeded - iK);
if (Ix2[0][0] < base.Ix2_min[0] || Ix2[0][base.Nrap[0]-1] > base.Ix2_max[0]) return(false);
(*this).Set_Label_from_Ix2 (OriginStateIx2);
return(true);
}
void Set_to_Outer_Skeleton (const Vect<Vect<int> >& OriginStateIx2) {
Ix2[0][0] = base.Ix2_min[0] - 4;
Ix2[0][base.Nrap[0]-1] = base.Ix2_max[0] + 4;
(*this).Set_Label_from_Ix2 (OriginStateIx2);
};
void Set_to_Closest_Matching_Ix2_fixed_Base (const Heis_Bethe_State& StateToMatch); // defined in Heis.cc
// Virtual functions, all defined in the derived classes
public:
virtual void Set_Free_lambdas() { JSCerror("Heis_Bethe_State::..."); } // sets the rapidities to solutions of BAEs without scattering terms
virtual bool Check_Admissibility(char option) { JSCerror("Heis_Bethe_State::..."); return(false); }
// verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
virtual void Compute_BE (int j, int alpha) { JSCerror("Heis_Bethe_State::..."); }
virtual void Compute_BE () { JSCerror("Heis_Bethe_State::..."); }
virtual DP Iterate_BAE(int i, int alpha) { JSCerror("Heis_Bethe_State::..."); return(0.0);}
virtual bool Check_Rapidities() { JSCerror("Heis_Bethe_State::..."); return(false); }
virtual DP String_delta () { JSCerror("Heis_Bethe_State::..."); return(0.0); }
virtual void Compute_Energy () { JSCerror("Heis_Bethe_State::..."); }
virtual void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red) { JSCerror("Heis_Bethe_State::..."); }
};
inline bool Is_Inner_Skeleton (Heis_Bethe_State& State) {
return (State.base.Nrap[0] >= 2 && (State.Ix2[0][0] == State.Ix2[0][1] - 2 || State.Ix2[0][State.base.Nrap[0]-1] == State.Ix2[0][State.base.Nrap[0]-2] + 2));
};
inline bool Is_Outer_Skeleton (Heis_Bethe_State& State) {
return (State.Ix2[0][0] == State.base.Ix2_min[0] - 4 && State.Ix2[0][State.base.Nrap[0]-1] == State.base.Ix2_max[0] + 4);
};
inline bool Force_Descent (char whichDSF, Heis_Bethe_State& ScanState, Heis_Bethe_State& RefState, int desc_type_required, int iKmod, DP Chem_Pot)
{
bool force_descent = false;
// Force descent if energy of ScanState is lower than that of RefState
//if (ScanState.E - RefState.E - (ScanState.base.Mdown - RefState.base.Mdown) < 0.0) return(true);
/*
// We force descent if
// 1) - there exists a higher string whose quantum number is still on 0
// AND - there is at most a single particle-hole in the 0 base level
// AND - either the particle or the hole hasn't yet moved.
if (ScanState.base_id/100000LL > 0) { // there is a higher string
int type0 = ScanState.type_id % 10000;
if (type0 == 0
|| type0 == 101 && ScanState.offsets.Tableau[0].id * ScanState.offsets.Tableau[2].id == 0LL
|| type0 == 110 && ScanState.offsets.Tableau[1].id * ScanState.offsets.Tableau[2].id == 0LL
|| type0 == 1001 && ScanState.offsets.Tableau[0].id * ScanState.offsets.Tableau[3].id == 0LL
|| type0 == 1010 && ScanState.offsets.Tableau[1].id * ScanState.offsets.Tableau[3].id == 0LL) // single p-h pair in base level 0
for (int j = 1; j < ScanState.chain.Nstrings; ++j) {
if (ScanState.base[j] == 1 && ScanState.Ix2[j][0] == 0) {
force_descent = true;
}
}
}
*/
// Force descent if quantum nr distribution is symmetric:
//if (ScanState.Check_Symmetry()) force_descent = true;
//if (desc_type_required > 8 && ScanState.Check_Symmetry()) force_descent = true;
// Force descent for longitudinal if we're at zero or pi momentum:
//ScanState.Compute_Momentum();
//if (whichDSF == 'z' && (ScanState.iK - RefState.iK) % iKmod == 0) force_descent = true;
//if (desc_type_required > 8 && whichDSF == 'z' && (2*(ScanState.iK - RefState.iK) % iKmod == 0)) force_descent = true; // type_req > 8 means that we don't conserve momentum
// Force descent for all DSFs if we're at K = 0 or PI and not conserving momentum upon descent:
if (desc_type_required > 8 && (2*(ScanState.iK - RefState.iK) % iKmod == 0)) force_descent = true; // type_req > 8 means that we don't conserve momentum
//if (force_descent) cout << "Forcing descent on state with label " << ScanState.label << endl;
if (ScanState.chain.Delta > 1.0) {
/*
// Count the nr of holes in one-strings:
int nholes = 0;
for (int i = 0; i < ScanState.base.Nrap[0] - 1; ++i) if (ScanState.Ix2[0][i+1] - ScanState.Ix2[0][i] != 2) nholes++;
if (nholes <= 2) {
if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 2 && ScanState.base.Nrap[1] == 1) force_descent = true;
if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 3 && ScanState.base.Nrap[2] == 1) force_descent = true;
if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 4 && ScanState.base.Nrap[1] == 2) force_descent = true;
}
*/
if (ScanState.label.compare(0, 10, "14x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "14x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "14x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "14x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "14x1y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "14x1y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_0x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_1x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_2x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_0x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_1x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_2x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_0x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_1x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_2x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_2x0") == 0) force_descent = true;
//if (ScanState.label.compare(0, 10, "62x1y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_2x1") == 0
&& (desc_type_required == 14 || desc_type_required == 13 || desc_type_required == 11 || desc_type_required == 10)) force_descent = true;
/*
if (ScanState.label.compare(0, 10, "60x1y2_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_0x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_1x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_2x1") == 0 && desc_type_required < 2) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_2x2") == 0 && desc_type_required < 2) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
*/
if (ScanState.label.compare(0, 11, "126x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "126x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "126x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "126x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "126x1y1_2x0") == 0) force_descent = true;
//if (ScanState.label.compare(0, 11, "126x1y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
if (ScanState.label.compare(0, 11, "126x1y1_2x1") == 0
&& (desc_type_required == 14 || desc_type_required == 13 || desc_type_required == 11 || desc_type_required == 10)) force_descent = true;
/*
if (ScanState.label.compare(0, 10, "124x1y2_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_0x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_1x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_2x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_2x1") == 0) force_descent = true;
*/
if (ScanState.label.compare(0, 11, "254x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "254x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "254x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "254x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "254x1y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "254x1y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
// Do not force descent a state with rapidities outside of fundamental interval:
/*
for (int j = 0; j < ScanState.chain.Nstrings; ++j) {
// Logic: allow rapidities -PI/2 <= lambda <= PI/2 (including boundaries)
if (ScanState.base.Nrap[j] > 0 &&
(ScanState.lambda[j][0] < -PI/2 || ScanState.lambda[j][ScanState.base.Nrap[j] - 1] > PI/2))
force_descent = false;
// rapidities should also be ordered as the quantum numbers:
for (int alpha = 1; alpha < ScanState.base.Nrap[j]; ++alpha)
if (ScanState.lambda[j][alpha - 1] >= ScanState.lambda[j][alpha])
force_descent = false;
}
*/
//if (force_descent) cout << "Forcing descent on state with label " << ScanState.label << endl;
} // if Delta > 1
//if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 2 && ScanState.base.Nrap[1] == 1 && ScanState.Ix2[1][0] == 0) force_descent = true;
//if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 3 && ScanState.base.Nrap[2] == 1 && ScanState.Ix2[2][0] == 0) force_descent = true;
//if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 4 && ScanState.base.Nrap[1] == 2 && ScanState.Ix2[1][0] == -1 && ScanState.Ix2[1][1] == 1) force_descent = true;
return(force_descent);
}
std::ostream& operator<< (std::ostream& s, const Heis_Bethe_State& state);
//****************************************************************************
// Objects in class XXZ_Bethe_State carry all extra information pertaining to XXZ gapless
class XXZ_Bethe_State : public Heis_Bethe_State {
public:
Lambda sinhlambda;
Lambda coshlambda;
Lambda tanhlambda;
public:
XXZ_Bethe_State ();
XXZ_Bethe_State (const XXZ_Bethe_State& RefState); // copy constructor
XXZ_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
XXZ_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base); // constructor to lowest-energy config with base
//XXZ_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with bas
public:
XXZ_Bethe_State& operator= (const XXZ_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
void Compute_sinhlambda();
void Compute_coshlambda();
void Compute_tanhlambda();
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
bool Check_Rapidities(); // checks that all rapidities are not nan
DP String_delta ();
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXZ specific functions:
public:
};
XXZ_Bethe_State Add_Particle_at_Center (const XXZ_Bethe_State& RefState);
XXZ_Bethe_State Remove_Particle_at_Center (const XXZ_Bethe_State& RefState);
//****************************************************************************
// Objects in class XXX_Bethe_State carry all extra information pertaining to XXX antiferromagnet
class XXX_Bethe_State : public Heis_Bethe_State {
public:
XXX_Bethe_State ();
XXX_Bethe_State (const XXX_Bethe_State& RefState); // copy constructor
XXX_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
XXX_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base); // constructor to lowest-energy config with base
//XXX_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with base
public:
XXX_Bethe_State& operator= (const XXX_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
bool Check_Rapidities(); // checks that all rapidities are not nan
DP String_delta ();
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXX specific functions
public:
bool Check_Finite_rap ();
};
XXX_Bethe_State Add_Particle_at_Center (const XXX_Bethe_State& RefState);
XXX_Bethe_State Remove_Particle_at_Center (const XXX_Bethe_State& RefState);
//****************************************************************************
// Objects in class XXZ_gpd_Bethe_State carry all extra information pertaining to XXZ gapped antiferromagnets
class XXZ_gpd_Bethe_State : public Heis_Bethe_State {
public:
Lambda sinlambda;
Lambda coslambda;
Lambda tanlambda;
public:
XXZ_gpd_Bethe_State ();
XXZ_gpd_Bethe_State (const XXZ_gpd_Bethe_State& RefState); // copy constructor
XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base); // constructor to lowest-energy config with base
//XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with base
public:
XXZ_gpd_Bethe_State& operator= (const XXZ_gpd_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
void Compute_sinlambda();
void Compute_coslambda();
void Compute_tanlambda();
int Weight(); // weight function for contributions cutoff
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
void Iterate_BAE_Newton();
bool Check_Rapidities(); // checks that all rapidities are not nan and are in interval ]-PI/2, PI/2]
DP String_delta ();
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXZ_gpd specific functions
public:
};
XXZ_gpd_Bethe_State Add_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState);
XXZ_gpd_Bethe_State Remove_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState);
//***********************************************
// Function declarations
// in M_vs_H.cc
DP Ezero (DP Delta, int N, int M);
DP H_vs_M (DP Delta, int N, int M);
DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref);
int M_vs_H (DP Delta, int N, DP HZ);
DP X_avg (char xyorz, DP Delta, int N, int M);
DP Chemical_Potential (const Heis_Bethe_State& RefState);
DP Particle_Hole_Excitation_Cost (char whichDSF, Heis_Bethe_State& AveragingState);
//DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& RefState, DP Chem_Pot, bool fixed_iK, int iKneeded);
DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
void Evaluate_F_Sumrule (string prefix, char whichDSF, const Heis_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
complex<DP> ln_Sz_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B);
complex<DP> ln_Smin_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B);
complex<DP> ln_Sz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
complex<DP> ln_Smin_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
// From Antoine Klauser:
complex<DP> ln_Szz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
complex<DP> ln_Szm_p_Smz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
complex<DP> ln_Smm_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
complex<DP> ln_Sz_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B);
complex<DP> ln_Smin_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B);
// The following functions have become member functions.
//DP String_delta (XXZ_Bethe_State& state);
//DP String_delta (XXX_Bethe_State& state);
//DP String_delta (XXZ_gpd_Bethe_State& state);
//DP Compute_Form_Factor_Entry (char whichDSF, Heis_Bethe_State& LeftState, Heis_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState,
// XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState,
XXZ_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState,
// XXX_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState,
XXX_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState,
// XXZ_gpd_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState,
XXZ_gpd_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
// For geometric quench:
complex<DP> ln_Overlap (XXX_Bethe_State& A, XXX_Bethe_State& B);
void Scan_Heis_Geometric_Quench (DP Delta, int N_1, int M, long long int base_id_1, long long int type_id_1, long long int id_1,
int N_2, int iKmin, int iKmax, int Max_Secs, bool refine);
} // namespace JSC
#endif
+32
View File
@@ -0,0 +1,32 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_Infprec.h
Purpose: Declarations for infinite precision arithmetic classes.
***********************************************************/
#ifndef _JSC_INFPREC_
#define _JSC_INFPREC_
namespace JSC {
class infprec_int {
private:
int nintrep; // number of integers used in representation
int baseint; // fundamental int
Vect<unsigned int> xint; // extra integers
}
} // namespace JSC
#endif
+331
View File
@@ -0,0 +1,331 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS++ library.
Copyright (c)
-----------------------------------------------------------
File: JSC_Integ.h
Purpose: Declares combinatorics-related classes and functions.
***********************************************************/
#ifndef _INTEG_
#define _INTEG_
#include "JSC.h"
namespace JSC {
//********************** Class Domain ************************
template<class T>
class Domain {
private:
Vect<T> bdry;
public:
Domain () : bdry(Vect<T>(2))
{
bdry[0] = T(0);
bdry[1] = T(0);
}
public:
Domain (T xmin_ref, T xmax_ref) : bdry(Vect<T>(2))
{
if (xmax_ref < xmin_ref) JSCerror("Use xmax > xmin in Domain.");
bdry[0] = xmin_ref;
bdry[1] = xmax_ref;
}
public:
inline T xmin (int i)
{
if (i > bdry.size()/2) JSCerror("i index too high in Domain::xmin.");
return(bdry[2*i]);
}
public:
inline T xmax (int i)
{
if (i > bdry.size()/2) JSCerror("i index too high in Domain::xmax.");
return(bdry[2*i + 1]);
}
public:
inline int Ndomains ()
{
return(bdry.size()/2);
}
public:
void Include (T xmin_ref, T xmax_ref) {
// Determine the indices of xmin_ref & xmax_ref
int xmin_reg = -1;
int xmax_reg = -1;
for (int i = 0; i < bdry.size(); ++i) {
if ((i+1) % 2 && bdry[i] <= xmin_ref) xmin_reg++;
if (i % 2 && bdry[i] < xmin_ref) xmin_reg++;
if ((i+1) % 2 && bdry[i] <= xmax_ref) xmax_reg++;
if (i % 2 && bdry[i] < xmax_ref) xmax_reg++;
}
//cout << "Include: xmin_reg = " << xmin_reg << "\txmax_reg = " << xmax_reg << endl;
Vect<T> new_bdry(bdry.size() + 2 * ((xmin_reg % 2 && xmax_reg % 2) - (xmax_reg - xmin_reg)/2));
int ishift = 0;
for (int i = 0; i <= xmin_reg; ++i) new_bdry[i] = bdry[i];
if (xmin_reg % 2) {
new_bdry[xmin_reg + 1] = xmin_ref;
ishift++;
if (xmax_reg % 2) {
new_bdry[xmin_reg + 2] = xmax_ref;
ishift++;
}
}
else if ((xmin_reg + 1) % 2 && xmax_reg % 2) {
new_bdry[xmin_reg + 1] = xmax_ref;
ishift++;
}
for (int i = xmin_reg + ishift + 1; i < new_bdry.size(); ++i)
new_bdry[i] = bdry[xmax_reg - xmin_reg - ishift + i];
bdry = new_bdry;
return;
}
public:
void Exclude (T xmin_ref, T xmax_ref) {
// Determine the indices of xmin_ref & xmax_ref
int xmin_reg = -1;
int xmax_reg = -1;
for (int i = 0; i < bdry.size(); ++i) {
if ((i+1) % 2 && bdry[i] <= xmin_ref) xmin_reg++;
if (i % 2 && bdry[i] < xmin_ref) xmin_reg++;
if ((i+1) % 2 && bdry[i] <= xmax_ref) xmax_reg++;
if (i % 2 && bdry[i] < xmax_ref) xmax_reg++;
}
//cout << "Exclude: xmin_reg = " << xmin_reg << "\txmax_reg = " << xmax_reg << endl;
Vect<T> new_bdry(bdry.size() + 2 * (((xmin_reg + 1) % 2 && (xmax_reg + 1) % 2) - (xmax_reg - xmin_reg)/2));
int ishift = 0;
for (int i = 0; i <= xmin_reg; ++i) new_bdry[i] = bdry[i];
if ((xmin_reg + 1) % 2) {
new_bdry[xmin_reg + 1] = xmin_ref;
ishift++;
if ((xmax_reg + 1) % 2) {
new_bdry[xmin_reg + 2] = xmax_ref;
ishift++;
}
}
else if (xmin_reg % 2 && (xmax_reg + 1) % 2) {
new_bdry[xmin_reg + 1] = xmax_ref;
ishift++;
}
for (int i = xmin_reg + ishift + 1; i < new_bdry.size(); ++i)
new_bdry[i] = bdry[xmax_reg - xmin_reg - ishift + i];
bdry = new_bdry;
return;
}
};
template<class T>
std::ostream& operator<< (std::ostream& s, Domain<T> dom)
{
for (int i = 0; i < dom.Ndomains(); ++i) {
if (i > 0) s << endl;
s << dom.xmin(i) << "\t" << dom.xmax(i);
}
return(s);
}
// ********************************* struct I_table ************************
struct I_table {
DP (*function) (DP, DP);
int Nvals;
DP rhomin;
DP rhomax;
DP alpha;
DP logalpha;
DP prec;
//Vect_DP rho_tbl;
//Vect_DP I_tbl;
DP* rho_tbl;
DP* I_tbl;
I_table (DP (*function) (DP, DP), DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec);
DP Return_val (DP req_rho);
void Save ();
bool Load (DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec);
};
// ********************************* struct Integral_table ************************
struct Integral_table {
DP (*function) (DP, DP, int);
int Nvals;
DP rhomin;
DP rhomax;
DP alpha;
DP logalpha;
DP prec;
int maxnrpts;
DP* rho_tbl;
DP* I_tbl;
Integral_table (DP (*function) (DP, DP, int), const char* filenameprefix_ref, DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec, int max_nr_pts);
DP Return_val (DP req_rho);
void Save (const char* filenameprefix);
bool Load (const char* filenameprefix, DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec, int max_nr_pts);
};
// ******************************** Recursive integration functions ******************************
DP Integrate_Riemann (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, int Npts);
DP Integrate_Riemann_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, int Npts);
DP Integrate_rec (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, DP req_prec, int max_rec_level);
DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int max_rec_level);
DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile);
DP Integrate_rec_using_table_and_file (DP (*function) (Vect_DP, I_table, ofstream&), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile);
// ******************************** Recursive version: optimal ******************************
struct data_pt {
DP x;
DP f;
DP dx;
};
struct Integral_result {
DP integ_est;
DP abs_prec;
DP rel_prec;
int n_vals;
};
std::ostream& operator<< (std::ostream& s, const Integral_result& res);
class Integral_data {
private:
data_pt* data;
DP* abs_d2f_dx; // second derivative * dx
DP max_abs_d2f_dx; //
public:
//int n_vals;
Integral_result integ_res;
public:
DP xmin;
DP xmax;
public:
Integral_data (DP (*function_ref) (Vect_DP), Vect_DP& args, int arg_to_integ_ref, DP xmin_ref, DP xmax_ref);
Integral_data (DP (*function_ref) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ_ref, I_table Itable, DP xmin_ref, DP xmax_ref);
Integral_data (DP (*function_ref) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ_ref, Integral_table Itable, DP xmin_ref, DP xmax_ref);
void Save (ofstream& outfile);
void Improve_estimate (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, int Npts_max);
void Improve_estimate (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, int Npts_max);
void Improve_estimate (DP (*function) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ, Integral_table Itable, int Npts_max);
~Integral_data ();
};
Integral_result Integrate_optimal (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, Integral_table Itable), Vect_DP& args, int arg_to_integ,
Integral_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile);
// ******************************** Recursive version: optimal, complex implementation ******************************
// NB: function returns complex values but takes real arguments
struct data_pt_CX {
DP x;
complex<DP> f;
DP dx;
};
struct Integral_result_CX {
complex<DP> integ_est;
DP abs_prec;
DP rel_prec;
int n_vals;
};
class Integral_data_CX {
private:
data_pt_CX* data;
DP* abs_d2f_dx; // second derivative * dx
DP max_abs_d2f_dx; //
public:
//int n_vals;
Integral_result_CX integ_res;
public:
DP xmin;
DP xmax;
public:
Integral_data_CX (complex<DP> (*function_ref) (Vect_DP), Vect_DP& args, int arg_to_integ_ref, DP xmin_ref, DP xmax_ref);
//Integral_data_CX (complex<DP> (*function_ref) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ_ref, I_table Itable, DP xmin_ref, DP xmax_ref);
void Save (ofstream& outfile);
void Improve_estimate (complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, int Npts_max);
//void Improve_estimate (complex<DP> (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, int Npts_max);
~Integral_data_CX ();
};
Integral_result_CX Integrate_optimal (complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax,
DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
//Integral_result_CX Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
// I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
//Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
// I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile);
} // namespace JSC
#endif
+190
View File
@@ -0,0 +1,190 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_LiebLin.h
Purpose: Declares LiebLin gas-related classes and functions.
***********************************************************/
#ifndef _LIEBLIN_
#define _LIEBLIN_
#include "JSC.h"
namespace JSC {
// First, some global constants...
//const DP ITER_REQ_PREC_LIEBLIN = 1.0e+6 * MACHINE_EPS_SQ;
const DP ITER_REQ_PREC_LIEBLIN = 1.0e+4 * MACHINE_EPS_SQ;
const int LIEBLIN_Ix2_MIN = -1000000; // Like a UV cutoff. Assumption: never reached in scanning.
const int LIEBLIN_Ix2_MAX = -LIEBLIN_Ix2_MIN;
//***********************************************************************
//class LiebLin_Bethe_State : public Bethe_State {
class LiebLin_Bethe_State {
public:
DP c_int; // interaction parameter
DP L;
DP cxL;
int N;
string label;
//Vect<int> OriginStateIx2; // quantum numbers of state on which excitations are built; always ordered
Vect<int> Ix2_available; // quantum numbers which are allowable but not occupied
Vect<int> index_first_hole_to_right;
Vect<int> displacement;
Vect<int> Ix2;
Vect<DP> lambdaoc;
//Vect<DP> BE;
Vect<DP> S; // scattering sum
Vect<DP> dSdlambdaoc; // its derivative
DP diffsq;
DP prec;
int conv;
int iter_Newton;
DP E;
int iK;
DP K;
DP lnnorm;
public:
LiebLin_Bethe_State ();
LiebLin_Bethe_State (DP c_int_ref, DP L_ref, int N_ref);
LiebLin_Bethe_State& operator= (const LiebLin_Bethe_State& RefState);
public:
int Charge () { return(N); };
void Set_to_Label (string label_ref, const Vect<int>& OriginStateIx2);
void Set_to_Label (string label_ref); // assumes OriginState == GroundState
void Set_Label_from_Ix2 (const Vect<int>& OriginStateIx2);
void Set_Label_Internals_from_Ix2 (const Vect<int>& OriginStateIx2);
bool Check_Admissibility(char whichDSF); // always returns true
void Find_Rapidities (bool reset_rapidities);
bool Check_Rapidities(); // checks that all rapidities are not nan
DP String_delta(); // trivially returns 0; exists to mirror spin chain function
bool Check_Symmetry (); // checks whether set of quantum numbers obeys { I } = { -I }
void Compute_lnnorm ();
void Compute_All (bool reset_rapidities); // solves BAE, computes E, K and lnnorm
void Set_Free_lambdaocs();
void Iterate_BAE(DP damping);
void Iterate_BAE_S(DP damping);
void Iterate_BAE_Newton(DP damping);
void Compute_Energy ();
void Compute_Momentum ();
DP Kernel (int a, int b);
DP Kernel (DP lambdaoc_ref);
void Build_Reduced_Gaudin_Matrix (SQMat<DP>& Gaudin_Red);
void Build_Reduced_BEC_Quench_Gaudin_Matrix (SQMat<DP>& Gaudin_Red);
void Annihilate_ph_pair (int ipart, int ihole, const Vect<int>& OriginStateIx2);
void Parity_Flip (); // takes all lambdaoc to -lambdaoc
inline bool Set_to_Inner_Skeleton (int iKneeded, const Vect<int>& OriginIx2)
{
if (N < 3) JSCerror("N<3 incompatible with fixed momentum scanning");
Ix2[0] = Ix2[1] - 2;
Ix2[N-1] = Ix2[N-2] + 2;
(*this).Compute_Momentum();
if (iKneeded >= iK) Ix2[N-1] += 2*(iKneeded - iK);
else Ix2[0] += 2*(iKneeded - iK);
if (Ix2[0] < LIEBLIN_Ix2_MIN || Ix2[N-1] > LIEBLIN_Ix2_MAX) return(false);
(*this).Set_Label_from_Ix2 (OriginIx2);
return(true);
}
void Set_to_Outer_Skeleton (const Vect<int>& OriginIx2)
{
Ix2[0] = LIEBLIN_Ix2_MIN + (N % 2) + 1;
Ix2[N-1] = LIEBLIN_Ix2_MAX - (N % 2) - 1;
(*this).Set_Label_from_Ix2 (OriginIx2);
//cout << "Set state to outer skeleton: Ix2 " << (*this).Ix2 << endl;
//cout << "label " << (*this).label << endl;
};
};
inline bool Is_Inner_Skeleton (LiebLin_Bethe_State& State) {
return (State.N >= 2 && (State.Ix2[0] == State.Ix2[1] - 2 || State.Ix2[State.N-1] == State.Ix2[State.N-2] + 2));
};
inline bool Is_Outer_Skeleton (LiebLin_Bethe_State& State) {
return (State.N >= 2 && State.Ix2[0] == LIEBLIN_Ix2_MIN + (State.N % 2) + 1 && State.Ix2[State.N-1] == LIEBLIN_Ix2_MAX - (State.N % 2) - 1);
};
inline bool Is_Outer_Skeleton (const LiebLin_Bethe_State& State) {
return (State.N >= 2 && State.Ix2[0] == LIEBLIN_Ix2_MIN + (State.N % 2) + 1 && State.Ix2[State.N-1] == LIEBLIN_Ix2_MAX - (State.N % 2) - 1);
};
inline bool Force_Descent (char whichDSF, LiebLin_Bethe_State& ScanState, LiebLin_Bethe_State& RefState, int desc_type_required, int iKmod, DP Chem_Pot)
{
bool forcedesc = false;
// Force descent if we're computing density-density, we're at zero momentum and we're descending with momentum preserved:
if (whichDSF == 'd' && ScanState.iK == RefState.iK && desc_type_required > 8) forcedesc = true;
// For BEC to c > 0 quench, g2(x=0): force first step
else if (whichDSF == 'B' && ScanState.label == RefState.label) forcedesc = true;
else if (whichDSF == 'C' && ScanState.label == RefState.label) forcedesc = true;
return(forcedesc);
}
std::ostream& operator<< (std::ostream& s, const LiebLin_Bethe_State& state);
// FUNCTION DECLARATIONS:
DP Chemical_Potential (LiebLin_Bethe_State& RefState);
DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
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 (string prefix, char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
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);
// in LiebLin_Utils.cc
DP LiebLin_dE0_dc (DP c_int, DP L, int N);
DP LiebLin_vs (DP c_int, DP L, int N);
DP LiebLin_Dressed_Charge_N (DP c_int, DP L, int N);
int Momentum_Right_Excitations (LiebLin_Bethe_State& ScanState);
int Momentum_Left_Excitations (LiebLin_Bethe_State& ScanState);
DP ln_Overlap_with_BEC (LiebLin_Bethe_State& lambda);
DP Particle_Hole_Excitation_Cost (char whichDSF, LiebLin_Bethe_State& AveragingState);
complex<DP> ln_Density_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate);
complex<DP> ln_Psi_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate);
complex<DP> ln_g2_ME (LiebLin_Bethe_State& mu, LiebLin_Bethe_State& lambda);
//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);
DP LiebLin_Twisted_lnnorm (Vect<complex<DP> >& lambdaoc, double cxL);
complex<DP> LiebLin_Twisted_ln_Overlap (DP expbeta, Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
complex<DP> LiebLin_Twisted_ln_Overlap (complex<DP> expbeta, Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
complex<DP> LiebLin_ln_Overlap (Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
complex<DP> LiebLin_ln_Overlap (Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
// In src/LiebLin_Tgt0.cc:
//DP Entropy_rho (LiebLin_Bethe_State& RefState, int Delta);
//DP Entropy_Fixed_Delta (LiebLin_Bethe_State& RefState, int Delta);
//DP Entropy (LiebLin_Bethe_State& RefState, int Delta);
DP Entropy (LiebLin_Bethe_State& RefState);
//DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, int Delta);
DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT);
//DP Entropy (LiebLin_Bethe_State& RefState, DP epsilon);
//DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, DP epsilon);
//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 (DP c_int, DP L, int N, DP kBT);
LiebLin_Bethe_State Add_Particle_at_Center (const LiebLin_Bethe_State& RefState);
LiebLin_Bethe_State Remove_Particle_at_Center (const LiebLin_Bethe_State& RefState);
DP rho_of_lambdaoc_1 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta);
DP rho_of_lambdaoc_2 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta);
} // namespace JSC
#endif
+440
View File
@@ -0,0 +1,440 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_Matrix.h
Purpose: Declares square matrix class.
***********************************************************/
#ifndef _MATRIX_
#define _MATRIX_
namespace JSC {
// CLASS DEFINITIONS
template <class T>
class SQMat {
private:
int dim;
T** M;
public:
SQMat (int N); // initializes all elements of this n by n matrix to zero
SQMat (const SQMat& rhs); // copy constructor
SQMat (const T& a, int N); // initialize to diagonal matrix with value a (NOT like in NR !!!)
SQMat (const SQMat& a, const SQMat& b); // initialize to tensor product of a and b
SQMat (const SQMat& a, int row_id, int col_id); // init by cutting row row_id and col col_id
void Print ();
SQMat& operator= (const SQMat& rhs); // assignment
SQMat& operator= (const T& a); // assign 1 to diagonal elements (NOT like in NR !!!)
inline T* operator[] (const int i); // subscripting: pointer to row i
inline const T* operator[] (const int i) const;
SQMat& operator+= (const T& a);
SQMat& operator+= (const SQMat& a);
SQMat& operator-= (const T& a);
SQMat& operator-= (const SQMat& a);
SQMat& operator*= (const T& a);
SQMat& operator*= (const SQMat& a);
inline int size() const;
~SQMat();
};
template <class T>
SQMat<T>::SQMat (int N) : dim(N) , M(new T*[N])
{
M[0] = new T[N*N];
for (int i = 1; i < N; i++) M[i] = M[i-1] + N;
}
template <class T>
SQMat<T>::SQMat (const SQMat& rhs) : dim(rhs.dim) , M(new T*[dim])
{
int i,j;
M[0] = new T[dim*dim];
for (i = 1; i < dim; i++) M[i] = M[i-1] + dim;
for (i = 0; i < dim; i++)
for (j = 0; j < dim; j++) M[i][j] = rhs[i][j];
}
template <class T>
SQMat<T>::SQMat (const T& a, int N) : dim(N) , M(new T*[dim])
{
int i, j;
M[0] = new T[dim*dim];
for (i = 1; i < dim; i++) M[i] = M[i-1] + dim;
for (i = 0; i < dim; i++) {
for (j = 0; j < dim; j++) M[i][j] = T(0);
M[i][i] = a;
}
}
template <class T>
SQMat<T>::SQMat (const SQMat& a, const SQMat& b) : dim (a.dim * b.dim) , M(new T*[a.dim * b.dim])
{
M[0] = new T[a.dim * b.dim * a.dim * b.dim];
for (int i = 1; i < a.dim * b.dim; ++i) M[i] = M[i-1] + a.dim * b.dim;
for (int i1 = 0; i1 < a.dim; ++i1) {
for (int i2 = 0; i2 < a.dim; ++i2) {
for (int j1 = 0; j1 < b.dim; ++j1) {
for (int j2 = 0; j2 < b.dim; ++j2) {
M[i1 * (b.dim) + j1][i2 * (b.dim) + j2] = a[i1][i2] * b[j1][j2];
}
}
}
}
}
template <class T>
SQMat<T>::SQMat (const SQMat&a, int row_id, int col_id) : dim (a.dim - 1) , M(new T*[dim])
{
if (dim == 0) {
JSCerror("Error: chopping a row and col from size one matrix.");
exit(1);
}
M[0] = new T[dim * dim];
for (int i = 1; i < dim; ++i) M[i] = M[i-1] + dim;
for (int i = 0; i < row_id; ++i)
for (int j = 0; j < col_id; ++j) M[i][j] = a[i][j];
for (int i = row_id; i < dim; ++i)
for (int j = 0; j < col_id; ++j) M[i][j] = a[i+1][j];
for (int i = 0; i < row_id; ++i)
for (int j = col_id; j < dim; ++j) M[i][j] = a[i][j+1];
for (int i = row_id; i < dim; ++i)
for (int j = col_id; j < dim; ++j) M[i][j] = a[i+1][j+1];
}
// operators
template <class T>
void SQMat<T>::Print ()
{
cout << endl;
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j) cout << M[i][j] << " ";
cout << endl;
}
cout << endl;
}
template <class T>
SQMat<T>& SQMat<T>::operator= (const SQMat<T>& rhs)
{
if (this != &rhs) {
if (dim != rhs.dim) {
JSCerror("Assignment between matrices of different dimensions. Bailing out.");
exit(1);
}
for (int i = 0; i < dim; ++i)
for (int j = 0; j < dim; ++j) M[i][j] = rhs[i][j];
}
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator= (const T& a)
{
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j)
M[i][j] = T(0);
M[i][i] = a;
}
return *this;
}
template <class T>
inline T* SQMat<T>::operator[] (const int i)
{
return M[i];
}
template <class T>
inline const T* SQMat<T>::operator[] (const int i) const
{
return M[i];
}
template <class T>
SQMat<T>& SQMat<T>::operator+= (const T& a)
{
for (int i = 0; i < dim; ++i) M[i][i] += a;
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator+= (const SQMat<T>& a)
{
if (dim != a.dim) {
JSCerror("Incompatible matrix sizes in matrix operator +.");
exit(1);
}
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j) {
M[i][j] += a[i][j];
}
}
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator-= (const T& a)
{
for (int i = 0; i < dim; ++i) M[i][i] -= a;
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator-= (const SQMat<T>& a)
{
if (dim != a.dim) {
JSCerror("Incompatible matrix sizes in matrix operator +.");
exit(1);
}
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j) {
M[i][j] -= a[i][j];
}
}
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator*= (const T& a)
{
for (int i = 0; i < dim; ++i) for (int j = 0; j < dim; ++j) M[i][j] *= a;
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator*= (const SQMat<T>& a)
{
if (dim != a.dim) {
JSCerror("Incompatible matrix sizes in matrix operator *.");
exit(1);
}
SQMat<T> leftarg(*this); // use copy constructor.
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j) {
M[i][j] = 0.0;
for (int k = 0; k < dim; ++k) {
M[i][j] += leftarg[i][k] * a[k][j];
}
}
}
return *this;
}
template <class T>
inline int SQMat<T>::size() const
{
return dim;
}
template <class T>
SQMat<T>::~SQMat()
{
if (M != 0) {
delete[] (M[0]);
delete[] (M);
}
}
//*****************************
template <class T>
class RecMat {
private:
int nrows;
int ncols;
T** M;
public:
RecMat (int Nrows, int Ncols); // initializes all elements of this n by n matrix to zero
RecMat (const T& a, int Nrows, int Ncols);
RecMat (const RecMat& rhs); // copy constructor
void Print ();
RecMat& operator= (const RecMat& rhs); // assignment
inline T* operator[] (const int i); // subscripting: pointer to row i
inline const T* operator[] (const int i) const;
inline int nr_rows() const;
inline int nr_cols() const;
~RecMat();
};
template <class T>
RecMat<T>::RecMat (int Nrows, int Ncols) : nrows(Nrows), ncols(Ncols), M(new T*[Nrows])
{
M[0] = new T[Nrows*Ncols];
for (int i = 1; i < Nrows; i++) M[i] = M[i-1] + Ncols;
for (int i = 0; i < Nrows; i++) for (int j = 0; j < Ncols; j++) M[i][j] = T(0);
}
template <class T>
RecMat<T>::RecMat (const T& a, int Nrows, int Ncols) : nrows(Nrows), ncols(Ncols), M(new T*[Nrows])
{
M[0] = new T[Nrows*Ncols];
for (int i = 1; i < Nrows; i++) M[i] = M[i-1] + Ncols;
for (int i = 0; i < Nrows; i++) for (int j = 0; j < Ncols; j++) {
if (i == j) M[i][i] = a;
else M[i][j] = T(0);
}
}
template <class T>
RecMat<T>::RecMat (const RecMat& rhs) : nrows(rhs.nrows), ncols(rhs.ncols), M(new T*[nrows])
{
int i,j;
M[0] = new T[nrows*ncols];
for (i = 1; i < nrows; i++) M[i] = M[i-1] + ncols;
for (i = 0; i < nrows; i++)
for (j = 0; j < ncols; j++) M[i][j] = rhs[i][j];
}
// operators
template <class T>
void RecMat<T>::Print ()
{
cout << endl;
for (int i = 0; i < nrows; ++i) {
for (int j = 0; j < ncols; ++j) cout << M[i][j] << " ";
cout << endl;
}
cout << endl;
}
template <class T>
RecMat<T>& RecMat<T>::operator= (const RecMat<T>& rhs)
{
if (this != &rhs) {
if (nrows != rhs.nrows || ncols != rhs.ncols) {
if (M != 0) {
delete[] (M[0]);
delete[] (M);
}
nrows = rhs.nrows;
ncols = rhs.ncols;
M = new T*[nrows];
M[0] = new T[nrows * ncols];
}
for (int i = 0; i < nrows; ++i)
for (int j = 0; j < ncols; ++j) M[i][j] = rhs[i][j];
}
return *this;
}
template <class T>
inline T* RecMat<T>::operator[] (const int i)
{
return M[i];
}
template <class T>
inline const T* RecMat<T>::operator[] (const int i) const
{
return M[i];
}
template <class T>
inline int RecMat<T>::nr_rows() const
{
return nrows;
}
template <class T>
inline int RecMat<T>::nr_cols() const
{
return ncols;
}
template <class T>
inline std::ostream& operator<< (std::ostream& s, const RecMat<T>& matrix)
{
for (int i = 0; i < matrix.nr_rows(); ++i) {
for (int j = 0; j < matrix.nr_cols(); ++j) s << matrix[i][j] << " ";
s << endl;
}
return (s);
}
template <class T>
RecMat<T>::~RecMat()
{
if (M != 0) {
delete[] (M[0]);
delete[] (M);
}
}
// TYPEDEFS:
typedef JSC::SQMat<DP> SQMat_DP;
typedef JSC::SQMat<complex<double> > SQMat_CX;
// FUNCTION DEFINITIONS
// Functions in src/MATRIX directory
DP det_LU (SQMat_DP a);
DP lndet_LU (SQMat_DP a);
complex<DP> lndet_LU_dstry (SQMat_DP& a);
complex<DP> det_LU_CX (SQMat_CX a);
complex<DP> lndet_LU_CX (SQMat_CX a);
complex<DP> lndet_LU_CX_dstry (SQMat_CX& a);
void eigsrt (Vect_DP& d, SQMat_DP& v);
void balanc (SQMat_DP& a);
void elmhes (SQMat_DP& a);
void gaussj (SQMat_DP& a, SQMat_DP& b);
void hqr (SQMat_DP& a, Vect_CX& wri);
void jacobi (SQMat_DP& a, Vect_DP& d, SQMat_DP& v, int& nrot);
void lubksb (SQMat_DP& a, Vect_INT& indx, Vect_DP& b);
void lubksb_CX (SQMat_CX& a, Vect_INT& indx, Vect_CX& b);
void ludcmp (SQMat_DP& a, Vect_INT& indx, DP& d);
void ludcmp_CX (SQMat_CX& a, Vect_INT& indx, DP& d);
DP pythag(DP a, DP b);
void tqli(Vect_DP& d, Vect_DP& e, SQMat_DP& z);
void tred2 (SQMat_DP& a, Vect_DP& d, Vect_DP& e);
} // namespace JSC
#endif
+36
View File
@@ -0,0 +1,36 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_NRG.h
Purpose: Declares NRG-related classes and functions.
***********************************************************/
#ifndef _NRG_
#define _NRG_
#include "JSC.h"
namespace JSC {
DP K_Weight_integrand (Vect_DP args); // weighing function for state selection
//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);
void Select_States_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required, bool symmetric_states, int iKmod,
//int weighing_option, DP (*weight_integrand_fn) (Vect_DP), Vect_DP& args_to_weight_integrand)
int weighing_option, Vect<complex <DP> >& FT_of_potential);
void Build_DFF_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 label_left_begin, int label_left_end, int label_right_begin, int label_right_end,
int block_option, DP* DFF_block_1, DP* DFF_block_2, Vect_DP Kweight);
}
#endif // _NRG_
+463
View File
@@ -0,0 +1,463 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: Heis.h
Purpose: Declares lattice spinless fermion classes and functions.
***********************************************************/
#ifndef _ODSLF_
#define _ODSLF_
#include "JSC.h"
namespace JSC {
//****************************************************************************
// Objects in class ODSLF_Base are a checked vector containing the number of rapidities of allowable types for a given state
class ODSLF_Base {
public:
int Mdown; // total number of down spins
Vect<int> Nrap; // Nrap[i] contains the number of rapidities of type i, i = 0, Nstrings - 1.
int Nraptot; // total number of strings in this state
Vect<DP> Ix2_infty; // Ix2_infty[i] contains the max of BAE function for the (half-)integer I[i], i = 0, Nstrings - 1.
Vect<int> Ix2_max; // Ix2_max[i] contains the integer part of 2*I_infty, with correct parity for base.
long long int id; // identification number
public:
ODSLF_Base ();
ODSLF_Base (const ODSLF_Base& RefBase); // copy constructor
ODSLF_Base (const Heis_Chain& RefChain, int M); // constructs configuration with all Mdown in one-string of +1 parity
ODSLF_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities); // sets to Nrapidities vector, and checks consistency
ODSLF_Base (const Heis_Chain& RefChain, long long int id_ref);
inline int& operator[] (const int i);
inline const int& operator[] (const int i) const;
ODSLF_Base& operator= (const ODSLF_Base& RefBase);
bool operator== (const ODSLF_Base& RefBase);
bool operator!= (const ODSLF_Base& RefBase);
void Compute_Ix2_limits(const Heis_Chain& RefChain); // computes the Ix2_infty and Ix2_max
void Scan_for_Possible_Types (Vect<long long int>& possible_type_id, int& nfound, int base_level, Vect<int>& Nexcitations);
Vect<long long int> Possible_Types (); // returns a vector of possible types
};
inline int& ODSLF_Base::operator[] (const int i)
{
return Nrap[i];
}
inline const int& ODSLF_Base::operator[] (const int i) const
{
return Nrap[i];
}
//****************************************************************************
// Objects in class ODSLF_Ix2_Config carry all the I's of a given state
class ODSLF_Ix2_Config {
//private:
public:
int Nstrings;
Vect<int> Nrap;
int Nraptot;
int** Ix2;
//Vect<Vect<int> > Ix2;
public:
ODSLF_Ix2_Config ();
ODSLF_Ix2_Config (const Heis_Chain& RefChain, int M); // constructor, puts I's to ground state
ODSLF_Ix2_Config (const Heis_Chain& RefChain, const ODSLF_Base& base); // constructor, putting I's to lowest-energy config
// consistent with Heis_Base configuration for chain RefChain
ODSLF_Ix2_Config& operator= (const ODSLF_Ix2_Config& RefConfig);
inline int* operator[] (const int i);
//inline Vect<int> operator[] (const int i);
inline const int* operator[] (const int i) const;
//inline const Vect<int> operator[] (const int i) const;
~ODSLF_Ix2_Config();
};
inline int* ODSLF_Ix2_Config::operator[] (const int i)
//inline Vect<int> Ix2_Config::operator[] (const int i)
{
return Ix2[i];
}
inline const int* ODSLF_Ix2_Config::operator[] (const int i) const
//inline const Vect<int> Ix2_Config::operator[] (const int i) const
{
return Ix2[i];
}
std::ostream& operator<< (std::ostream& s, const ODSLF_Ix2_Config& RefConfig);
//****************************************************************************
// Objects in class ODSLF_Lambda carry all rapidities of a state
class ODSLF_Lambda {
private:
int Nstrings;
Vect<int> Nrap;
int Nraptot;
DP** lambda;
//Vect<Vect<DP> > lambda;
public:
ODSLF_Lambda ();
ODSLF_Lambda (const Heis_Chain& RefChain, int M); // constructor, puts all lambda's to zero
ODSLF_Lambda (const Heis_Chain& RefChain, const ODSLF_Base& base); // constructor, putting I's to lowest-energy config
// consistent with Heis_Base configuration for chain RefChain
ODSLF_Lambda& operator= (const ODSLF_Lambda& RefConfig);
inline DP* operator[] (const int i);
//inline Vect<DP> operator[] (const int i);
inline const DP* operator[] (const int i) const;
//inline const Vect<DP> operator[] (const int i) const;
~ODSLF_Lambda();
};
inline DP* ODSLF_Lambda::operator[] (const int i)
//inline Vect<DP> Lambda::operator[] (const int i)
{
return lambda[i];
}
inline const DP* ODSLF_Lambda::operator[] (const int i) const
//inline const Vect<DP> Lambda::operator[] (const int i) const
{
return lambda[i];
}
//****************************************************************************
// Objects in class ODSLF_Ix2_Offsets carry Young tableau representations of the Ix2 configurations
class ODSLF_Ix2_Offsets {
public:
ODSLF_Base base;
Vect<Young_Tableau> Tableau; // vector of pointers to tableaux at each level
long long int type_id;
long long int id; // id number of offset
long long int maxid; // max id number allowable
public:
ODSLF_Ix2_Offsets ();
ODSLF_Ix2_Offsets (const ODSLF_Ix2_Offsets& RefOffset); // copy constructor
ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, long long int req_type_id);
ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, Vect<int> nparticles); // sets all tableaux to empty ones, with nparticles[] at each level
ODSLF_Ix2_Offsets& operator= (const ODSLF_Ix2_Offsets& RefOffset);
bool operator<= (const ODSLF_Ix2_Offsets& RefOffsets);
bool operator>= (const ODSLF_Ix2_Offsets& RefOffsets);
public:
void Set_to_id (long long int idnr);
void Compute_id ();
void Compute_type_id ();
public:
bool Add_Boxes_From_Lowest (int Nboxes, bool odd_sectors); // adds Nboxes in minimal energy config, all boxes in either even or odd sectors
};
inline long long int ODSLF_Ix2_Offsets_type_id (Vect<int>& nparticles)
{
long long int type_id_here = 0ULL;
for (int i = 0; i < nparticles.size(); ++i)
type_id_here += nparticles[i] * pow_ulli(10ULL, i);
return(type_id_here);
}
//****************************************************************************
// Objects in class ODSLF_Ix2_Offsets_List carry a vector of used Ix2_Offsets
class ODSLF_Ix2_Offsets_List {
public:
int ndef;
Vect<ODSLF_Ix2_Offsets> Offsets;
public:
ODSLF_Ix2_Offsets_List ();
ODSLF_Ix2_Offsets& Return_Offsets (ODSLF_Base& RefBase, Vect<int> nparticles); // returns the Ix2_Offsets corresponding to nparticles[]/base
ODSLF_Ix2_Offsets& Return_Offsets (ODSLF_Base& RefBase, long long int req_type_id);
};
//****************************************************************************
// Objects in class ODSLF_Bethe_State carry all information about an eigenstate
// Derived classes include XXZ_Bethe_State, XXX_Bethe_State, XXZ_gpd_Bethe_State
// These contain subclass-specific functions and data.
class ODSLF_Bethe_State {
public:
Heis_Chain chain;
ODSLF_Base base;
ODSLF_Ix2_Offsets offsets;
ODSLF_Ix2_Config Ix2;
ODSLF_Lambda lambda;
ODSLF_Lambda BE; // Bethe equation for relevant rapidity, in the form BE = theta - (1/N)\sum ... - \pi I/N = 0
DP diffsq; // sum of squares of rapidity differences in last iteration
int conv; // convergence status
int iter; // number of iterations necessary for convergence
int iter_Newton; // number of iterations necessary for convergence (Newton method)
DP E; // total energy
int iK; // K = 2.0*PI * iK/Nsites
DP K; // total momentum
DP lnnorm; // ln of norm of reduced Gaudin matrix
//long long int id;
//long long int maxid;
long long int base_id;
long long int type_id;
long long int id;
long long int maxid;
int nparticles;
public:
ODSLF_Bethe_State ();
ODSLF_Bethe_State (const ODSLF_Bethe_State& RefState); // copy constructor
ODSLF_Bethe_State (const ODSLF_Bethe_State& RefState, long long int type_id_ref); // new state with requested type_id
ODSLF_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
ODSLF_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& base); // constructor to lowest-energy config with base
ODSLF_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref);
virtual ~ODSLF_Bethe_State () {};
public:
int Charge () { return(base.Mdown); };
//void Set_I_Offset (const I_Offset& RefOffset); // sets the Ix2 to given offsets
void Set_Ix2_Offsets (const ODSLF_Ix2_Offsets& RefOffset); // sets the Ix2 to given offsets
void Set_to_id (long long int id_ref);
void Set_to_id (long long int id_ref, ODSLF_Bethe_State& RefState);
int Nparticles (); // counts the number of particles in state once Ix2 offsets set (so type_id is correctly set)
bool Check_Symmetry (); // checks whether the I's are symmetrically distributed
void Compute_diffsq (); // \sum BE[j][alpha]^2
void Iterate_BAE (); // Finds new set of lambda[j][alpha] from previous one by simple iteration
void Iterate_BAE_Newton (); // Finds new set of lambda[j][alpha] from previous one by a Newton step
void Find_Rapidities (bool reset_rapidities); // Finds the rapidities
void Find_Rapidities_Twisted (bool reset_rapidities, DP twist); // Finds the rapidities with twist added to RHS of logBE
void BAE_smackdown (DP max_allowed);
void Solve_BAE_smackdown (DP max_allowed, int maxruns);
void Solve_BAE (int j, int alpha, DP req_prec, int itermax);
void Solve_BAE_interp (DP interp_prec, int max_iter_interp);
void Solve_BAE_straight_iter (DP interp_prec, int max_iter_interp);
void Solve_BAE_Newton (DP Newton_prec, int max_iter_Newton);
void Compute_lnnorm ();
void Compute_Momentum ();
void Compute_All (bool reset_rapidities); // solves BAE, computes E, K and lnnorm
bool Boost_Momentum (int iKboost);
// Virtual functions, all defined in the derived classes
public:
virtual void Set_Free_lambdas() { JSCerror("ODSLF_Bethe_State::..."); } // sets the rapidities to solutions of BAEs without scattering terms
virtual bool Check_Admissibility(char option) { JSCerror("ODSLF_Bethe_State::..."); return(false); }
// verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
virtual void Compute_BE (int j, int alpha) { JSCerror("ODSLF_Bethe_State::..."); }
virtual void Compute_BE () { JSCerror("ODSLF_Bethe_State::..."); }
virtual DP Iterate_BAE(int i, int alpha) { JSCerror("ODSLF_Bethe_State::..."); return(0.0);}
virtual bool Check_Rapidities() { JSCerror("ODSLF_Bethe_State::..."); return(false); }
virtual void Compute_Energy () { JSCerror("ODSLF_Bethe_State::..."); }
virtual void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red) { JSCerror("ODSLF_Bethe_State::..."); }
};
inline bool Force_Descent (char whichDSF, ODSLF_Bethe_State& ScanState, ODSLF_Bethe_State& RefState, int desc_type_required, int iKmod, DP Chem_Pot)
{
JSCerror("Need to implement Force_Descent properly for ODSLF.");
bool force_descent = false;
// Force descent if energy of ScanState is lower than that of RefState
if (ScanState.E - RefState.E - (ScanState.base.Mdown - RefState.base.Mdown) < 0.0) return(true);
/*
// We force descent if
// 1) - there exists a higher string whose quantum number is still on 0
// AND - there is at most a single particle-hole in the 0 base level
// AND - either the particle or the hole hasn't yet moved.
if (RefState.base_id/100000LL > 0) { // there is a higher string
int type0 = RefState.type_id % 10000;
if (type0 == 0
|| type0 == 101 && RefState.offsets.Tableau[0].id * RefState.offsets.Tableau[2].id == 0LL
|| type0 == 110 && RefState.offsets.Tableau[1].id * RefState.offsets.Tableau[2].id == 0LL
|| type0 == 1001 && RefState.offsets.Tableau[0].id * RefState.offsets.Tableau[3].id == 0LL
|| type0 == 1010 && RefState.offsets.Tableau[1].id * RefState.offsets.Tableau[3].id == 0LL) // single p-h pair in base level 0
for (int j = 1; j < RefState.chain.Nstrings; ++j) {
if (RefState.base[j] == 1 && RefState.Ix2[j][0] == 0) {
force_descent = true;
}
}
}
*/
// Force descent if quantum nr distribution is symmetric:
if (RefState.Check_Symmetry()) force_descent = true;
return(force_descent);
}
std::ostream& operator<< (std::ostream& s, const ODSLF_Bethe_State& state);
//****************************************************************************
// Objects in class XXZ_Bethe_State carry all extra information pertaining to XXZ gapless
class ODSLF_XXZ_Bethe_State : public ODSLF_Bethe_State {
public:
ODSLF_Lambda sinhlambda;
ODSLF_Lambda coshlambda;
ODSLF_Lambda tanhlambda;
public:
ODSLF_XXZ_Bethe_State ();
ODSLF_XXZ_Bethe_State (const ODSLF_XXZ_Bethe_State& RefState); // copy constructor
ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& base); // constructor to lowest-energy config with base
ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with bas
public:
ODSLF_XXZ_Bethe_State& operator= (const ODSLF_XXZ_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
void Compute_sinhlambda();
void Compute_coshlambda();
void Compute_tanhlambda();
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
bool Check_Rapidities(); // checks that all rapidities are not nan
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXZ specific functions:
public:
};
//****************************************************************************
/*
// Objects in class ODSLF_XXX_Bethe_State carry all extra information pertaining to XXX antiferromagnet
class ODSLF_XXX_Bethe_State : public ODSLF_Bethe_State {
public:
ODSLF_XXX_Bethe_State ();
ODSLF_XXX_Bethe_State (const ODSLF_XXX_Bethe_State& RefState); // copy constructor
ODSLF_XXX_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
ODSLF_XXX_Bethe_State (const Heis_Chain& RefChain, const ODSLF__Base& base); // constructor to lowest-energy config with base
ODSLF_XXX_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with base
public:
ODSLF_XXX_Bethe_State& operator= (const ODSLF_XXX_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
bool Check_Rapidities(); // checks that all rapidities are not nan
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXX specific functions
public:
bool Check_Finite_rap ();
};
*/
//****************************************************************************
/*
// Objects in class ODSLF_XXZ_gpd_Bethe_State carry all extra information pertaining to XXZ gapped antiferromagnets
class ODSLF_XXZ_gpd_Bethe_State : public ODSLF__Bethe_State {
public:
Lambda sinlambda;
Lambda coslambda;
Lambda tanlambda;
public:
ODSLF_XXZ_gpd_Bethe_State ();
ODSLF_XXZ_gpd_Bethe_State (const ODSLF_XXZ_gpd_Bethe_State& RefState); // copy constructor
ODSLF_XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
ODSLF_XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& base); // constructor to lowest-energy config with base
ODSLF_XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with base
public:
ODSLF_XXZ_gpd_Bethe_State& operator= (const ODSLF_XXZ_gpd_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
void Compute_sinlambda();
void Compute_coslambda();
void Compute_tanlambda();
int Weight(); // weight function for contributions cutoff
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
void Iterate_BAE_Newton();
bool Check_Rapidities(); // checks that all rapidities are not nan and are in interval ]-PI/2, PI/2]
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXZ_gpd specific functions
public:
};
*/
//***********************************************
// Function declarations
/*
// in M_vs_H.cc
DP Ezero (DP Delta, int N, int M);
DP H_vs_M (DP Delta, int N, int M);
DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref);
int M_vs_H (DP Delta, int N, DP HZ);
DP X_avg (char xyorz, DP Delta, int N, int M);
*/
DP Chemical_Potential (const ODSLF_Bethe_State& RefState);
//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);
void Evaluate_F_Sumrule (string prefix, char whichDSF, const ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B);
complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B);
//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);
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, ODSLF_XXZ_Bethe_State& LeftState,
ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
} // namespace JSC
#endif
+1263
View File
File diff suppressed because it is too large Load Diff
+207
View File
@@ -0,0 +1,207 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_Spec_Fns.h
Purpose: Defines special math functions.
***********************************************************/
#ifndef _JSC_SPEC_FNS_H_
#define _JSC_SPEC_FNS_H_
#include "JSC.h"
using namespace std;
namespace JSC {
inline DP Cosine_Integral (DP x)
{
// Returns the Cosine integral -\int_x^\infty dt \frac{\cos t}{t}
// Refer to GR[6] 8.23
if (x <= 0.0) {
cout << "Cosine_Integral called with real argument " << x << " <= 0, which is ill-defined because of the branch cut." << endl;
JSCerror("");
}
else if (x < 15.0) { // Use power series expansion
// Ci (x) = gamma + \ln x + \sum_{n=1}^\infty (-1)^n x^{2n}/(2n (2n)!).
int n = 1;
DP minonetothen = -1.0;
DP logxtothetwon = 2.0 * log(x);
DP twologx = 2.0 * log(x);
DP logtwonfact = log(2.0);
DP series = minonetothen * exp(logxtothetwon - log(2.0 * n) - logtwonfact);
DP term_n;
do {
n += 1;
minonetothen *= -1.0;
logxtothetwon += twologx;
logtwonfact += log((2.0 * n - 1.0) * 2.0 * n);
term_n = minonetothen * exp(logxtothetwon - log(2.0 * n) - logtwonfact);
series += term_n;
} while (fabs(term_n) > 1.0e-16);
/*
// For improved convergence we pair terms up, DOESN'T WORK WELL
// Ci (x) = gamma + \ln x - \sum{n = 1, 3, 5, ...} \frac{x^{2n}}{2n (2n)!} ( 1 - \frac{n}{n+1} \frac{x^2}{(2n+1)(2n+2)} )
int n = 1;
DP logxtothetwon = 2.0 * log(x);
DP logtwon = log(2.0);
DP logtwonfact = log(2.0);
DP xsq = x*x;
DP series = exp(logxtothetwon - logtwon - logtwonfact) * (1 - xsq/((2.0 * n + 1.0) * (2.0 * n + 2.0) * (1.0 + 1.0/n)));
DP term_n;
DP twologx = 2.0 * log(x);
do {
n += 2;
logxtothetwon += twologx;
logtwonfact += log((2.0 * n - 1.0) * 2.0 * n);
term_n = exp(logxtothetwon - log(2.0 * n) - logtwonfact) * (1 - xsq/((2.0 * n + 1.0) * (2.0 * n + 2.0) * (1.0 + 1.0/n)));;
series += term_n;
} while (fabs(term_n) > 1.0e-16);
*/
return(Euler_Mascheroni + log(x) + series);
}
else { // Use high x power series
// Ci (x) = \frac{\sin x}{x} \sum_{n=0}^\infty (-1)^n (2n)! x^{-2n} - \frac{\cos x}{x} \sum_{n=0}^\infty (-1)^n (2n+1)! x^{-2n-1}
int n = 0;
DP minonetothen = 1.0;
DP logxtothetwon = 0.0;
DP logxtothetwonplus1 = log(x);
DP twologx = 2.0 * log(x);
DP logtwonfact = 0.0;
DP logtwonplus1fact = 0.0;
DP series1 = minonetothen * exp(logtwonfact - logxtothetwon);
DP series2 = minonetothen * exp(logtwonplus1fact - logxtothetwonplus1);
do {
n += 1;
minonetothen *= -1.0;
logxtothetwon += twologx;
logxtothetwonplus1 += twologx;
logtwonfact += log((2.0 * n - 1.0) * 2.0 * n);
logtwonplus1fact += log(2.0 * n * (2.0 * n + 1));
series1 += minonetothen * exp(logtwonfact - logxtothetwon);
series2 += minonetothen * exp(logtwonplus1fact - logxtothetwonplus1);
} while (n < 12);
return((sin(x)/x) * series1 - (cos(x)/x) * series2);
}
return(log(-1.0));
}
/*********** Jacobi Theta functions *********/
inline DP Jacobi_Theta_1_q (DP u, DP q) {
// Uses the summation formula.
// theta_1 (x) = 2 \sum_{n=1}^\infty (-1)^{n+1} q^{(n-1/2)^2} \sin (2n-1)u
// in which q is the nome. (GR 8.180.1)
// We always evaluate to numerical accuracy.
if (q >= 1.0) JSCerror("Jacobi_Theta_1_q function called with q > 1.");
DP answer = 0.0;
DP contrib = 0.0;
DP qtonminhalfsq = pow(q, 0.25); // this will be q^{(n-1/2)^2}
DP qtotwon = pow(q, 2.0); // this will be q^{2n}
DP qsq = q*q;
int n = 1;
do {
contrib = (n % 2 ? 2.0 : -2.0) * qtonminhalfsq * sin((2.0*n - 1.0)*u);
answer += contrib;
qtonminhalfsq *= qtotwon;
qtotwon *= qsq;
n++;
//cout << "\t\tn = " << n << "\tanswer = " << answer << "\tcontrib = " << contrib << "\tqtonminhalfsq = " << qtonminhalfsq << "\tqtotwon = " << qtotwon << endl;
} while (fabs(contrib/answer) > MACHINE_EPS);
//cout << "\t\tJacobi_Theta_1: used " << n << " iterations." << "\tanswer = " << answer << "\tcontrib = " << contrib << "\tqtonminhalfsq = " << qtonminhalfsq << "\tqtotwon = " << qtotwon << endl;
return(answer);
}
inline complex<DP> ln_Jacobi_Theta_1_q (complex<DP> u, complex<DP> q) {
// This uses the product representation
// \theta_1 (x) = 2 q^{1/4} \sin{u} \prod_{n=1}^\infty (1 - 2 q^{2n} \cos 2u + q^{4n}) (1 - q^{2n})
// (GR 8.181.2)
complex<DP> contrib = 0.0;
complex<DP> qtotwon = q*q; // this will be q^{2n}
complex<DP> qsq = q*q;
complex<DP> twocos2u = 2.0 * cos(2.0*u);
int n = 1;
complex<DP> answer = log(2.0 * sin(u)) + 0.25 * log(q);
do {
contrib = log((1.0 - twocos2u * qtotwon + qtotwon * qtotwon) * (1.0 - qtotwon));
answer += contrib;
qtotwon *= qsq;
n++;
} while (abs(contrib) > 1.0e-12);
return(answer);
}
/************ Barnes function ************/
inline DP ln_Gamma_for_Barnes_G_RE (Vect_DP args)
{
return(real(ln_Gamma(complex<double>(args[0]))));
}
inline DP ln_Barnes_G_RE (DP z)
{
// Implementation according to equation (28) of 2004_Adamchik_CPC_157
// Restricted to real arguments.
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;
Integral_result integ_ln_Gamma = Integrate_optimal (ln_Gamma_for_Barnes_G_RE, args, 0, 0.0, z - 1.0, req_rel_prec, req_abs_prec, max_nr_pts);
return(0.5 * (z - 1.0) * (2.0 - z + logtwoPI) + (z - 1.0) * real(ln_Gamma(complex<double>(z - 1.0))) - integ_ln_Gamma.integ_est);
}
} // namespace JSC
#endif // _JS_SPEC_FNS_H_
+47
View File
@@ -0,0 +1,47 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_State_Ensemble.h
Purpose: Define state ensembles.
***********************************************************/
#ifndef _ENS_
#define _ENS_
#include "JSC.h"
namespace JSC {
struct LiebLin_Diagonal_State_Ensemble {
int nstates;
Vect<LiebLin_Bethe_State> state;
Vect<DP> weight;
LiebLin_Diagonal_State_Ensemble ();
LiebLin_Diagonal_State_Ensemble (const LiebLin_Bethe_State& RefState, int nstates_req);
//LiebLin_Diagonal_State_Ensemble (const LiebLin_Bethe_State& RefState, int nstates_req, const Vect<DP>& weight_ref);
//LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho, int nstates_req);
LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho);
LiebLin_Diagonal_State_Ensemble& operator= (const LiebLin_Diagonal_State_Ensemble& rhs);
void Load (DP c_int, DP L, int N, const char* ensfile_Cstr);
void Save (const char* ensfile_Cstr);
};
//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);
} // namespace JSC
#endif
+147
View File
@@ -0,0 +1,147 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS. library.
Copyright (c).
-----------------------------------------------------------
File: JSC_TBA.h
Purpose: Thermodynamic Bethe Ansatz general functions
***********************************************************/
#ifndef _TBA_
#define _TBA_
#include "JSC.h"
namespace JSC {
struct Root_Density {
int Npts; // how many points are used to describe each function
DP lambdamax; // what the largest rapidity is
Vect_DP lambda; // rapidity vector
Vect_DP dlambda; // differential element
Vect_DP value; // the root density itself
Vect_DP prev_value; // results of previous iteration
DP diff; // relative differences with previous iteration
bool value_infty_set; // boolean, true if asymptotic value set
DP value_infty; // asymptotic value, computed analytically
Root_Density ();
Root_Density (int Npts_ref, DP lambdamax_ref);
Root_Density& operator= (const Root_Density& RefDensity);
void Save (const char* outfile_Cstr);
DP Return_Value (DP lambda_ref); // evaluates the function for any argument using linear interpolation
void Set_Asymptotics (DP value_infty_ref); // sets value for lambda >= lambdamax
Root_Density Compress_and_Match_Densities (DP comp_factor); // returns a Root_Density with fewer points
};
struct Root_Density_Set {
int ntypes;
Vect<Root_Density> epsilon;
int Npts_total; // sum of all Npts of epsilon's
DP diff; // sum of diff's of the epsilon's
Root_Density_Set ();
Root_Density_Set (int ntypes_ref, int Npts_ref, DP lambdamax_ref);
Root_Density_Set (int ntypes_ref, Vect_INT Npts_ref, Vect_DP lambdamax_ref);
Root_Density_Set& operator= (const Root_Density_Set& RefSet);
void Insert_new_function (DP asymptotic_value);
void Extend_limits (Vect<bool> need_to_extend_limit);
void Insert_new_points (Vect<Vect<bool> > need_new_point_around);
DP Return_Value (int n_ref, DP lambda_ref); // returns a value, no matter what.
Root_Density_Set Return_Compressed_and_Matched_Set (DP comp_factor);
void Match_Densities (Root_Density_Set& RefSet);
void Save (const char* outfile_Cstr);
};
struct LiebLin_TBA_Solution {
DP c_int;
DP mu;
DP kBT;
DP nbar;
DP ebar; // mean energy, \int d\lambda \lambda^2 \rho (\lambda)
DP sbar; // entropy per unit length
Root_Density epsilon;
Root_Density depsilon_dmu;
Root_Density rho;
Root_Density rhoh;
LiebLin_TBA_Solution (DP c_int_ref, DP mu_ref, DP kBT_ref, DP req_diff, int Max_Secs);
};
// Functions defined in TBA_LiebLin.cc
Root_Density LiebLin_rho_GS (DP c_int, DP k_F, DP lambdamax, int Npts, DP req_prec);
DP Density_GS (Root_Density& rho_GS);
DP k_F_given_n (DP c_int, DP n, DP lambdamax, int Npts, DP req_prec);
Root_Density LiebLin_Z_GS (DP c_int, DP k_F, DP lambdamax, int Npts, DP req_prec);
Root_Density LiebLin_Fbackflow_GS (DP c_int, DP k_F, DP lambdamax, DP lambda, int Npts, DP req_prec);
// epsilon for a given mu:
Root_Density LiebLin_epsilon_TBA (DP c_int, DP mu, DP kBT, DP req_diff, int Max_Secs);
// depsilon/dmu for a given mu:
Root_Density LiebLin_depsilon_dmu_TBA (DP c_int, DP mu, DP kBT, DP req_diff, int Max_Secs, const Root_Density& epsilon);
Root_Density LiebLin_rho_TBA (DP kBT, const Root_Density& epsilon, const Root_Density& depsilon_dmu);
Root_Density LiebLin_rhoh_TBA (DP kBT, const Root_Density& epsilon, const Root_Density& depsilon_dmu);
DP LiebLin_nbar_TBA (const Root_Density& rho);
DP LiebLin_ebar_TBA (const Root_Density& rho);
DP LiebLin_sbar_TBA (const Root_Density& rho, const Root_Density& rhoh);
LiebLin_TBA_Solution LiebLin_TBA_Solution_fixed_nbar (DP c_int, DP nbar_required, DP kBT, DP req_diff, int Max_Secs);
LiebLin_TBA_Solution LiebLin_TBA_Solution_fixed_nbar_ebar (DP c_int, DP nbar_required, DP ebar_required, DP req_diff, int Max_Secs);
LiebLin_Bethe_State Discretized_LiebLin_Bethe_State (DP c_int, DP L, int N, const Root_Density& rho);
// Functions defined in TBA_XXZ.cc
DP XXZ_phi1_kernel (DP zeta, DP lambda);
DP XXZ_phi2_kernel (DP zeta, DP lambda);
DP XXZ_a1_kernel (DP sinzeta, DP coszeta, DP lambda);
DP XXZ_da1dlambda_kernel (DP sinzeta, DP coszeta, DP lambda);
DP XXZ_a2_kernel (DP sin2zeta, DP cos2zeta, DP lambda);
Root_Density XXZ_rhotot_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
DP Return_GS_Sz_tot_value (DP B, Root_Density& rhotot_GS);
Root_Density XXZ_eps_GS (DP Delta, DP Hz, DP lambdamax, int Npts, DP req_prec);
Root_Density XXZ_depsdlambda_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
Root_Density XXZ_b2BB_lambda_B (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
Root_Density XXZ_b2BB_lambda_lambdap (DP Delta, DP B, DP lambdap, DP lambdamax, int Npts, DP req_prec);
Root_Density XXZ_Kbackflow_GS (DP Delta, DP B, DP lambdamax, DP lambda_p, DP lambda_h, int Npts, DP req_prec);
Root_Density XXZ_Fbackflow_GS (DP Delta, DP B, DP lambdamax, DP lambda_p, DP lambda_h, int Npts, DP req_prec);
Root_Density XXZ_Z_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
//void XXZ_Compare_Lattice_and_Continuum_Backflows_base_1010 (DP Delta, int N, int M, long long int id);
// Defined in TBA_2CBG.cc:
struct TBA_Data_2CBG {
DP c_int;
DP mu;
DP Omega;
DP kBT;
DP f; // Gibbs free energy
DP n1; // first population
DP n2; // second population
};
// Defined in src/TBA_2CBG.cc:
TBA_Data_2CBG Solve_2CBG_TBAE_via_refinements (DP c_int, DP mu, DP Omega, DP kBT, int Max_Secs, bool Save_data);
// Defined in src/TBA_2CBG.cc:
void Scan_2CBG_TBAE (DP c_int, DP mu_min, DP mu_max, int Nmu, DP Omega_min, DP Omega_max, int NOmega,
DP kBT_min, DP kBT_max, int NkBT, int Max_Secs);
} // namespace JSC
#endif
+472
View File
@@ -0,0 +1,472 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS++ library.
Copyright (c)
-----------------------------------------------------------
File: JSC_Vect.h
Purpose: Declares vector class.
***********************************************************/
#ifndef _JSC_VECT_
#define _JSC_VECT_
namespace JSC {
template <class T>
class Vect {
private:
int dim;
T* V;
public:
Vect();
explicit Vect (int N);
Vect (const T& a, int N); // initialize all N elements are a
Vect (const T* a, int N); // initialize to array
Vect (const Vect& rhs); // Copy constructor
Vect& operator= (const Vect& rhs); // assignment
Vect& operator= (const T& a); // assign a to all elements
inline T& operator[] (const int i);
inline const T& operator[] (const int i) const;
Vect& operator+= (const Vect& rhs);
Vect& operator-= (const Vect& rhs);
bool operator== (const Vect& rhs); // checks equality of size and of all elements
bool operator!= (const Vect& rhs); // checks inequality
bool Append (const T& rhs); // appends rhs to the vector
bool Append (const Vect& rhs); // appends rhs to the vector
bool Increase_Size (int nr_to_add); // resizes the array to accommodate nr_to_add more entries
bool Increase_Size (int nr_to_add, T setval); // resizes the array to accommodate nr_to_add more entries
inline int size() const;
inline double norm() const; // returns norm of vector
inline T max() const; // returns maximal value
inline T min() const; // returns maximal value
inline T sum() const; // returns sum of all elements
inline bool includes(T check) const; // whether check == one of the elements or not
void QuickSort (int l, int r);
void QuickSort (Vect<int>& index, int l, int r);
void QuickSort ();
void QuickSort (Vect<int>& index);
~Vect();
};
template <class T>
Vect<T>::Vect() : dim(0), V(0) {}
template <class T>
Vect<T>::Vect (int N) : dim(N), V(new T[N]) {}
template <class T>
Vect<T>::Vect (const T& a, int N) : dim(N), V(new T[N])
{
for (int i = 0; i < N; ++i) V[i] = a;
}
template <class T>
Vect<T>::Vect (const T* a, int N) : dim(N), V(new T[N])
{
for (int i = 0; i < N; ++i) V[i] = *a++;
}
template <class T>
Vect<T>::Vect (const Vect<T>& rhs) : dim(rhs.dim), V(new T[dim])
{
for (int i = 0; i < dim; ++i) V[i] = rhs[i];
}
template <class T>
Vect<T>& Vect<T>::operator= (const Vect<T>& rhs)
{
if (this != &rhs) {
if (dim != rhs.dim) {
if (V != 0) delete[] V;
dim = rhs.dim;
V = new T[dim];
}
for (int i = 0; i < dim; ++i) V[i] = rhs[i];
}
return *this;
}
template <class T>
Vect<T>& Vect<T>::operator= (const T& a)
{
for (int i = 0; i < dim; ++i) V[i] = a;
return *this;
}
template <class T>
inline T& Vect<T>::operator[] (const int i)
{
return V[i];
}
template <class T>
inline const T& Vect<T>::operator[] (const int i) const
{
return V[i];
}
template <class T>
Vect<T>& Vect<T>::operator+= (const Vect<T>& rhs)
{
for (int i = 0; i < dim; ++i) V[i] += rhs[i];
return *this;
}
template <class T>
Vect<T>& Vect<T>::operator-= (const Vect<T>& rhs)
{
for (int i = 0; i < dim; ++i) V[i] -= rhs[i];
return *this;
}
template <class T>
bool Vect<T>::operator== (const Vect<T>& rhs)
{
bool answer = ((*this).size() == rhs.size());
if (answer) {
for (int i = 0; i < dim; ++i) answer = (answer && (V[i] == rhs[i]));
}
return answer;
}
template <class T>
bool Vect<T>::operator!= (const Vect<T>& rhs)
{
return(!((*this) == rhs));
}
template <class T>
bool Vect<T>::Append (const Vect<T>& rhs) // appends rhs to the vector
{
T* newvect = new T[dim + rhs.size()];
for (int i = 0; i < dim; ++i) newvect[i] = V[i];
for (int i = 0; i < rhs.size(); ++i) newvect[i+ dim] = rhs[i];
dim += rhs.size();
delete[] V;
V = new T[dim];
for (int i = 0; i < dim; ++i) V[i] = newvect[i];
delete[] newvect;
return(true);
}
template <class T>
bool Vect<T>::Append (const T& rhs) // appends rhs to the vector
{
T* newvect = new T[dim + 1];
for (int i = 0; i < dim; ++i) newvect[i] = V[i];
newvect[dim] = rhs;
dim += 1;
delete[] V;
V = new T[dim];
for (int i = 0; i < dim; ++i) V[i] = newvect[i];
delete[] newvect;
return(true);
}
template <class T>
bool Vect<T>::Increase_Size (int nr_to_add) // resizes the array to accommodate nr_to_add more entries
{
int resized_dim = dim + nr_to_add;
T* resized_vect = new T[resized_dim];
for (int i = 0; i < dim; ++i) resized_vect[i] = V[i];
for (int i = dim; i < resized_dim; ++i) resized_vect[i] = T(0);
dim = resized_dim;
delete[] V;
V = new T[dim];
for (int i = 0; i < dim; ++i) V[i] = resized_vect[i];
delete[] resized_vect;
return(true);
}
template <class T>
bool Vect<T>::Increase_Size (int nr_to_add, T setval) // resizes the array to accommodate nr_to_add more entries
{
int resized_dim = dim + nr_to_add;
T* resized_vect = new T[resized_dim];
for (int i = 0; i < dim; ++i) resized_vect[i] = V[i];
for (int i = dim; i < resized_dim; ++i) resized_vect[i] = setval;
dim = resized_dim;
delete[] V;
V = new T[dim];
for (int i = 0; i < dim; ++i) V[i] = resized_vect[i];
delete[] resized_vect;
return(true);
}
template <class T>
inline int Vect<T>::size() const
{
return dim;
}
template <class T>
inline double Vect<T>::norm () const
{
double normsq = 0.0;
for (int i = 0; i < dim; ++i) normsq += abs(V[i]) * abs(V[i]);
return sqrt(normsq);
}
template <>
inline double Vect<double>::norm () const
{
double normsq = 0.0;
for (int i = 0; i < dim; ++i) normsq += V[i] * V[i];
return(sqrt(normsq));
}
template <>
inline double Vect<complex<double> >::norm () const
{
double normsq = 0.0;
for (int i = 0; i < dim; ++i) normsq += std::norm(V[i]);
return(sqrt(normsq));
}
template <class T>
inline T Vect<T>::max() const
{
T maxval = V[0];
for (int i = 0; i < dim; ++i) if (V[i] > maxval) maxval = V[i];
return maxval;
}
template <class T>
inline T Vect<T>::min() const
{
T minval = V[0];
for (int i = 0; i < dim; ++i) if (V[i] < minval) minval = V[i];
return minval;
}
template <class T>
inline T Vect<T>::sum() const
{
T total = T(0);
for (int i = 0; i < dim; ++i) total += V[i];
return total;
}
template <class T>
inline bool Vect<T>::includes (T check) const
{
int index = 0;
while (index < dim && V[index] != check) index++;
return(index < dim);
}
/*
template <class T>
void Vect<T>::QuickSort (int l, int r)
{
//cout << "QuickSort called for l = " << l << "\t r = " << r << endl;
//cout << (*this) << endl;
//for (int ih = l; ih <= r; ++ih) cout << setprecision(16) << "ih = " << ih << "\tV[ih] = " << V[ih] << endl;
static T m;
static int j;
int i;
if (r > l) {
m = V[r]; i = l-1; j = r;
for (;;) {
while (V[++i] < m);
while (V[--j] > m);
if (i >= j) break;
std::swap(V[i], V[j]);
}
std::swap(V[i], V[r]);
(*this).QuickSort(l, i-1);
(*this).QuickSort(i+1, r);
}
}
*/
/*
template <class T>
void Vect<T>::QuickSort (int l, int r)
{
// My own version of QuickSort: add sentinels on left and right
if (r > l) {
int s = l + (r-l)/2; // central element index
// Rearrange so that V[l] <= V[s] <= V[r] (sentinels on left and right)
if (V[l] > V[r]) std::swap(V[l],V[r]);
if (V[s] > V[r]) std::swap(V[s],V[r]);
if (V[l] > V[s]) std::swap(V[l],V[s]);
m = V[s]; i = l-1; j = r;
//m = V[r]; i = l-1; j = r;
for (;;) {
while (V[i] < m) i++;
while (V[j] > m) j--;
if (i >= j) break;
std::swap(V[i], V[j]); // restart from indices i and j just used, in case one is pivot
}
//std::swap(V[i], V[r]);
(*this).QuickSort(l, i-1);
(*this).QuickSort(i+1, r);
}
}
*/
template <class T>
void Vect<T>::QuickSort (int l, int r)
{
int i = l, j = r;
T pivot = V[l + (r-l)/2];
while (i <= j) {
while (V[i] < pivot) i++;
while (V[j] > pivot) j--;
if (i <= j) {
std::swap(V[i],V[j]);
i++;
j--;
}
};
if (l < j) (*this).QuickSort(l, j);
if (i < r) (*this).QuickSort(i, r);
}
template <class T>
void Vect<T>::QuickSort ()
{
if ((*this).size() > 1) (*this).QuickSort (0, (*this).size() - 1);
}
/*
template <class T>
void Vect<T>::QuickSort (Vect<int>& index, int l, int r)
{
if (index.size() != (*this).size()) {
cout << (*this).size() << "\t" << index.size() << endl;
JSCerror("Wrong dim for index in Vect QuickSort.");
}
static T m;
static int j;
int i;
if (r > l) {
m = V[r]; i = l-1; j = r;
for (;;) {
while (V[++i] < m);
while (V[--j] > m);
if (i >= j) break;
std::swap(V[i], V[j]);
std::swap(index[i], index[j]);
}
std::swap(V[i], V[r]);
std::swap(index[i], index[r]);
(*this).QuickSort(index, l, i-1);
(*this).QuickSort(index, i+1, r);
}
}
*/
/*
template <class T>
void Vect<T>::QuickSort (Vect<int>& index, int l, int r)
{
// My own version of QuickSort:
if (r > l) {
int s = l + (r-l)/2; // central element index
// Rearrange so that V[l] <= V[s] <= V[r] (sentinels on left and right)
if (V[l] > V[r]) std::swap(V[l],V[r]);
if (V[s] > V[r]) std::swap(V[s],V[r]);
if (V[l] > V[s]) std::swap(V[l],V[s]);
m = V[s]; i = l-1; j = r+1;
for (;;) {
while (V[++i] < m);
while (V[--j] > m);
if (i >= j) break;
std::swap(index[i], index[j]);
std::swap(V[i--], V[j++]); // restart from indices i and j just used, in case one is pivot
}
(*this).QuickSort(index, l, i-1);
(*this).QuickSort(index, i+1, r);
}
}
*/
template <class T>
void Vect<T>::QuickSort (Vect<int>& index, int l, int r)
{
int i = l, j = r;
T pivot = V[l + (r-l)/2];
while (i <= j) {
while (V[i] < pivot) i++;
while (V[j] > pivot) j--;
if (i <= j) {
std::swap(V[i],V[j]);
std::swap(index[i],index[j]);
i++;
j--;
}
};
if (l < j) (*this).QuickSort(index, l, j);
if (i < r) (*this).QuickSort(index, i, r);
}
template <class T>
void Vect<T>::QuickSort (Vect<int>& index)
{
if (index.size() != (*this).size()) JSCerror("Wrong dim for index in Vect QuickSort.");
(*this).QuickSort (index, 0, (*this).size() - 1);
}
template <class T>
inline std::ostream& operator<< (std::ostream& s, const Vect<T>& vector)
{
for (int i = 0; i < vector.size() - 1; ++i) s << vector[i] << " ";
if (vector.size() >= 1) s << vector[vector.size() - 1];
return (s);
}
template <class T>
Vect<T>::~Vect<T>()
{
if (V != 0) delete[] V;
}
// TYPEDEFS
typedef JSC::Vect<int> Vect_INT;
typedef JSC::Vect<double> Vect_DP;
typedef JSC::Vect<complex<double> > Vect_CX;
} // namespace JSC
#endif
+139
View File
@@ -0,0 +1,139 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_XXX_h0.h
Purpose: Declares classes for XXX in zero field: Uq(sl(2)) stuff.
***********************************************************/
#ifndef _XXX_h0_
#define _XXX_h0_
#include "JSC.h"
const DP default_req_prec = 1.0e-14;
const int default_max_rec = 10;
namespace JSC {
inline DP Integrand_11 (Vect_DP args)
{
// args[0] corresponds to t, args[1] to rho
return((exp(args[0]) * sinh(args[0]) * cos(4.0 * args[0] * args[1])/(2.0 * pow(cosh(args[0]), 2.0)) + 2.0 * pow(sin(2.0 * args[0] * args[1]), 2.0))/args[0]);
}
inline DP Integrand_12 (Vect_DP args)
{
DP expm2t = exp(-2.0*args[0]);
return(cos(4.0 * args[0] * args[1]) * expm2t * (3.0 + expm2t)/ (args[0] * (1.0 + expm2t) * (1.0 + expm2t)));
}
inline DP Integrand_2 (Vect_DP args)
{
DP answer = 0.0;
if (args[0] < 1.0) answer = exp(args[0]) * pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * sinh(args[0]) * pow(cosh(args[0]), 2.0));
else if (args[0] >= 1.0) {
DP expm2t = exp(-2.0 * args[0]);
answer = 8.0 * expm2t * pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * (1.0 - expm2t) * (1.0 + expm2t) * (1.0 + expm2t));
}
return(answer);
}
inline DP Integrand_A (Vect_DP args)
{
// This kernel is for -ln | A_-(i\pi/2) | function
return(exp(args[0]) * pow(sinh(args[0]/2.0), 2.0)/(args[0] * sinh(2.0*args[0]) * cosh(args[0])));
}
DP I_integral (DP rho, DP req_prec);
/********************* TWO SPINONS ********************/
DP SF_2p (DP k, DP omega, I_table Itable);
DP SF_2p (Vect_DP args, I_table Itable);
DP SF_2p_alt (Vect_DP args, I_table Itable);
DP SF_2p_w (Vect_DP args, I_table Itable);
DP SF_2p_w_alt (Vect_DP args, I_table Itable);
DP SF_2p_intw (Vect_DP args, I_table Itable);
DP SF_2p_intw_alt (Vect_DP args, I_table Itable);
DP SF_2p_check_sumrule (DP req_prec, int max_rec, I_table Itable);
DP SF_2p_check_sumrule_alt (DP req_prec, int max_rec, I_table Itable);
DP Fixed_k_sumrule_w (DP k);
DP Fixed_k_sumrule_omega (DP k);
DP SF_2p_check_fixed_k_sumrule (DP k, DP req_prec, int max_rec, I_table Itable);
DP SF_2p_check_fixed_k_sumrule_alt (DP k, DP req_prec, int max_rec, I_table Itable);
DP SF_2p_check_fixed_k_sumrule_opt (DP k, DP req_prec, int Npts, I_table Itable);
/********************** FOUR SPINONS **********************/
DP Sum_norm_gl (Vect_DP rho, DP req_prec);
DP Compute_C4 (DP req_prec);
DP SF_contrib (Vect_DP p, DP req_prec, I_table Itable);
DP J_fn (Vect_DP p, DP req_prec, I_table Itable);
inline DP Jacobian_p3p4_KW (DP k, DP w, DP K, DP W)
{
return(1.0/sqrt(pow(twoPI * sin(0.5 * (k - K)), 2.0) - (w-W)*(w-W)));
}
bool Set_p_given_kwKW (DP k, DP w, DP K, DP W, Vect_DP& p);
inline DP wmin_4p (DP k)
{
return(PI * fabs(sin(k)));
}
inline DP wmax_4p (DP k)
{
return(2.0 * PI * sqrt(2.0 * (1.0 + fabs(cos(0.5*k)))));
}
inline DP Wmin (DP k, DP w, DP K)
{
return(JSC::max(1.0e-15, JSC::max(fabs(PI * sin(K)), w - twoPI * sin(0.5 * (fabs(k-K))))));
}
inline DP Wmax (DP k, DP w, DP K)
{
return(JSC::min(twoPI * sin(0.5 * K), w - fabs(PI * sin(k - K))));
}
DP G_fn (Vect_DP args_to_G, I_table Itable);
DP G1_fn (Vect_DP args_to_G, I_table Itable);
DP G2_fn (Vect_DP args_to_G, I_table Itable);
DP G1_fn_mid (Vect_DP args_to_G, I_table Itable);
DP G2_fn_mid (Vect_DP args_to_G, I_table Itable);
DP G_fn_alt (Vect_DP args_to_G, I_table Itable);
DP H_fn (Vect_DP args_to_H, I_table Itable);
DP H2_fn (Vect_DP args_to_H, I_table Itable);
DP H_fn_mid (Vect_DP args_to_H, I_table Itable);
DP H_fn_alt (Vect_DP args_to_H, I_table Itable);
DP SF_4p_kwKW (Vect_DP args, I_table Itable);
DP SF_4p_kwKW_alpha (Vect_DP args, I_table Itable);
DP SF_4p_kwKW_alpha_opt (Vect_DP args, I_table Itable);
// Interface to used version:
DP SF_4p_rec (DP k, DP omega, DP req_prec, int max_rec, I_table Itable);
DP SF_4p (DP k, DP omega, I_table Itable);
DP SF_4p_opt (DP k, DP omega, DP req_prec, int Npts_K, int Npts_W, I_table Itable);
void Translate_raw_4p_data (DP k, int max_rec_w, const char* SFraw_Cstr, const char* SF_Cstr, const char* SFsrc_Cstr, I_table Itable);
DP SF_4p_rec (DP k, DP req_prec, int max_rec_w, int max_rec, I_table Itable);
Integral_result SF_4p_opt (DP k, DP req_prec, int Npts, I_table Itable);
Integral_result SF_4p_opt (DP k, DP req_prec, int Npts_w, int Npts_KW, I_table Itable);
Integral_result SF_4p_opt (DP k, DP req_prec, int Npts_w, int Npts_K, int Npts_W, I_table Itable);
//******************************** Functions to produce files similar to ABACUS **********************************
void Produce_SF_2p_file (int N, int Nomega, DP omegamax, I_table Itable);
void Produce_SF_4p_file (int N, int Nomega, DP omegamax, DP req_prec, int max_rec, I_table Itable);
void Produce_SF_4p_file (int N, int Nomega, DP omegamax, DP req_prec, int Npts_K, int Npts_W, I_table Itable);
//******************************** New version, full k and omega integral in one go ******************************
DP Direct_J_integral (int Npts_p, DP req_prec, I_table Itable);
DP Direct_J_integral_bin (int Npts_p, int Npts_o, DP req_prec, I_table Itable);
void Smoothen_raw_SF_4p (int Npts_p, int Npts_o, DP req_prec, DP width);
} // namespace JSC
#endif
+86
View File
@@ -0,0 +1,86 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_XXZ_h0.h
Purpose: Declares classes for XXZ in zero field: quantum group stuff.
***********************************************************/
#ifndef _XXZ_h0_
#define _XXZ_h0_
#include "JSC.h"
//const DP default_req_prec = 1.0e-14;
//const int default_max_rec = 10;
namespace JSC {
/*
inline DP Integrand_xi_11 (Vect_DP args)
{
// args[0] corresponds to t, args[1] to rho, args[2] to xi
//return((exp(args[0]) * sinh(args[0]) * cos(4.0 * args[0] * args[1])/(2.0 * pow(cosh(args[0]), 2.0)) + 2.0 * pow(sin(2.0 * args[0] * args[1]), 2.0))/args[0]);
return((sinh(args[0]*(1.0 + args[2])) * sinh(args[0]) * cos(4.0 * args[0] * args[1])/(2.0 * sinh(args[0] * args[2]) * pow(cosh(args[0]), 2.0))
+ 2.0 * pow(sin(2.0 * args[0] * args[1]), 2.0))/args[0]);
}
inline DP Integrand_xi_12 (Vect_DP args)
{
DP expm2t = exp(-2.0*args[0]);
DP expm2txi = exp(-2.0*args[0]*args[2]);
//return(cos(4.0 * args[0] * args[1]) * expm2t * (3.0 + expm2t)/ (args[0] * (1.0 + expm2t) * (1.0 + expm2t)));
return(cos(4.0 * args[0] * args[1]) * (expm2t * (3.0 * (1.0 + expm2txi) + expm2t) + expm2txi) / (args[0] * (1.0 - expm2txi) * (1.0 + expm2t) * (1.0 + expm2t)));
}
*/
/*
inline DP Integrand_xi_2 (Vect_DP args)
{
DP answer = 0.0;
if (args[0] < 1.0)
//answer = exp(args[0]) * pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * sinh(args[0]) * pow(cosh(args[0]), 2.0));
answer = sinh(args[0] * (args[2] + 1.0)) * pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * sinh(args[2] * args[0]) * sinh(args[0]) * pow(cosh(args[0]), 2.0));
else if (args[0] >= 1.0) {
DP expm2t = exp(-2.0 * args[0]);
DP expm2txi = exp(-2.0*args[0]*args[2]);
//answer = 8.0 * expm2t * pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * (1.0 - expm2t) * (1.0 + expm2t) * (1.0 + expm2t));
answer = 8.0 * ((1.0 - expm2t*expm2txi)/(1.0 - expm2t*expm2txi)) * expm2t *
pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * (1.0 - expm2t) * (1.0 + expm2t) * (1.0 + expm2t));
}
return(answer);
}
*/
DP I_xi_integral (DP xi, DP rho, DP req_prec, int max_nr_pts);
/********************* TWO SPINONS ********************/
DP Szz_XXZ_h0_2spinons (DP k, DP omega, Integral_table Itable);
DP Szz_XXZ_h0_2spinons (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_alt (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_omega (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_omega_alt (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_intomega (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_intomega_alt (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_check_sumrule (DP Delta, DP req_prec, int max_nr_pts, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_check_sumrule_alt (DP Delta, DP req_prec, int max_nr_pts, Integral_table Itable);
DP Fixed_k_sumrule_omega_Szz_XXZ_h0_N (DP Delta, DP k);
DP GSE_XXZ_h0 (DP Delta, DP req_prec, int max_nr_pts);
DP Fixed_k_sumrule_omega_Szz_XXZ_h0 (DP Delta, DP k, DP req_prec, int max_nr_pts);
DP Szz_XXZ_h0_2spinons_check_fixed_k_Szz_sumrule (DP Delta, DP k, DP req_prec, int max_nr_pts, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_check_fixed_k_Szz_sumrule_alt (DP Delta, DP k, DP req_prec, int max_nr_pts, Integral_table Itable);
//******************************** Functions to produce files similar to ABACUS **********************************
void Produce_Szz_XXZ_h0_2spinons_file (DP Delta, int N, int Nomega, DP omegamax, Integral_table Itable);
void Produce_Szz_XXZ_h0_2spinons_fixed_K_file (DP Delta, DP Kover2PI, int Nomega, Integral_table Itable);
} // namespace JSC
#endif
+118
View File
@@ -0,0 +1,118 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_Young.h
Purpose: Declares Young tableau class.
***********************************************************/
#ifndef _YOUNG_
#define _YOUNG_
#include "JSC_Vect.h"
namespace JSC {
const int YOUNG_TABLEAU_ID_OPTION = 0;
const long long int TABLEAU_ID_UPPER_LIMIT = 10000000LL;
//***********************************************************************
class Young_Tableau {
public:
int Nrows;
int Ncols;
int* Row_L;
int* Col_L;
long long int id; // identification number
long long int maxid;
long long int* map;
bool map_computed;
long long int idnr_reached;
int nboxes_reached;
private:
int dimchoose;
long long int* choose_table;
public:
Young_Tableau (); // empty constructor, does nothing
Young_Tableau (int Nr, int Nc); // constructs empty tableau
Young_Tableau (int Nr, int Nc, long long int idnr); // constructs the tableau corresponding to identification number idnr
Young_Tableau (const Young_Tableau& RefTableau); // copy constructor
Young_Tableau (int Nr, int Nc, const Young_Tableau& RefTableau);
Young_Tableau& operator= (const Young_Tableau& RefTableau); // assignment
~Young_Tableau (); // destructor
public:
Young_Tableau& Compute_Map (long long int idnr_to_reach); // fills the map vector
Young_Tableau& Distribute_boxes (int nboxes_to_dist, int level);
Young_Tableau& Set_to_id (long long int idnr); // sets the tableau to the one corresponding to idnr
Young_Tableau& Set_to_id (long long int idnr, int option); // sets the tableau to the one corresponding to idnr according to rule option
Young_Tableau& Set_Row_L (Vect<int>& Row_Lengths); // set row lengths
Young_Tableau& Set_Col_L_given_Row_L (); // sets the Col_L array self-consistently
Young_Tableau& Set_Row_L_given_Col_L (); // sets the Col_L array self-consistently
long long int Compute_Descendent_id (int option, Vect<int>& Desc_Row_L, int Nrows_Desc, int Ncols_Desc,
const Young_Tableau& RefTableau);
Young_Tableau& Compute_id(); // computes the id number of tableau
Young_Tableau& Compute_id(int option); // computes the id number of tableau according to rule option
Young_Tableau& Print(); // couts the tableau
bool Lower_Row (int i);
bool Raise_Row (int i);
bool Lower_Col (int i);
bool Raise_Col (int i);
bool Raise_Lowest_Nonzero_Row(); // adds a box to the lowest nonzero length Row, recomputes id, returns true if tableau has changed
bool Raise_Next_to_Lowest_Nonzero_Row(); // same thing, but for Row under lowest nonzero length one.
bool Move_Box_from_Col_to_Col (int ifrom, int ito);
Vect<Young_Tableau> Descendents (int fixed_Nboxes);
Vect<Young_Tableau> Descendents_Boosted_State (int fixed_Nboxes);
int Add_Boxes_From_Lowest (int Nboxes); // tries to add Nboxes to Tableau, returns number of boxes added.
};
std::ostream& operator<< (std::ostream& s, const Young_Tableau& tableau);
inline int Nr_Nonzero_Rows (const Vect<Young_Tableau>& Tableau_ref)
{
// This function checks the number of rows containing at least one box
// in the whole vector of Young tableaux given as argument.
// The usefulness is to force descent of states in which only a few
// excitations have started dispersing.
int nr_nonzero_rows = 0;
for (int i = 0; i < Tableau_ref.size(); ++i)
for (int alpha = 0; alpha < Tableau_ref[i].Nrows; ++alpha)
if (Tableau_ref[i].Row_L[alpha] > 0) nr_nonzero_rows++;
return(nr_nonzero_rows);
}
//***********************************************************************
class Tableau_Map {
public:
Vect<long long int> map;
long long int idnr_reached;
int nboxes_reached;
public:
Tableau_Map (int Nrows, int Ncols);
void Distribute_id (int nboxes_to_dist, int level, Young_Tableau& RefTableau);
};
} // namespace JSC
#endif
+485
View File
@@ -0,0 +1,485 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_util.h
Purpose: Defines basic math functions.
***********************************************************/
#ifndef _JSC_UTIL_H_
#define _JSC_UTIL_H_
#include "JSC.h"
using namespace std;
typedef double DP;
// Global constants
const double PI = 3.141592653589793238462643;
const double sqrtPI = sqrt(PI);
const double twoPI = 2.0*PI;
const double logtwoPI = log(twoPI);
const double Euler_Mascheroni = 0.577215664901532860606;
const double Gamma_min_0p5 = -2.0 * sqrt(PI);
const complex<double> II(0.0,1.0); // Shorthand for i
const DP MACHINE_EPS = numeric_limits<DP>::epsilon();
const DP MACHINE_EPS_SQ = pow(MACHINE_EPS, 2.0);
// Now for some basic math utilities:
namespace JSC {
// File checks:
inline bool file_exists (const char* filename)
{
fstream file;
file.open(filename);
bool exists = !file.fail();
file.close();
return(exists);
}
// Error handler:
inline void JSCerror (const string error_text)
// my error handler
{
cerr << "Run-time error... " << endl;
cerr << error_text << endl;
cerr << "Exiting to system..." << endl;
exit(1);
}
struct Divide_by_zero {};
// Basics: min, max, fabs
template<class T>
inline const T max (const T& a, const T& b) { return a > b ? (a) : (b); }
template<class T>
inline const T min (const T& a, const T& b) { return a > b ? (b) : (a); }
template<class T>
inline const T fabs (const T& a) { return a >= 0 ? (a) : (-a); }
inline long long int pow_lli (const long long int& base, const int& exp)
{
long long int answer = base;
if (exp == 0) answer = 1LL;
else for (int i = 1; i < exp; ++i) answer *= base;
return(answer);
}
inline unsigned long long int pow_ulli (const unsigned long long int& base, const int& exp)
{
unsigned long long int answer = base;
if (exp == 0) answer = 1ULL;
for (int i = 1; i < exp; ++i) answer *= base;
return(answer);
}
inline int fact (const int& N)
{
int ans = 0;
if (N < 0) {
cerr << "Error: factorial of negative number. Exited." << endl;
exit(1);
}
else if ( N == 1 || N == 0) ans = 1;
else ans = N * fact(N-1);
return(ans);
}
inline DP ln_fact (const int& N)
{
DP ans = 0.0;
if (N < 0) {
cerr << "Error: factorial of negative number. Exited." << endl;
exit(1);
}
else if ( N == 1 || N == 0) ans = 0.0;
else ans = log(DP(N)) + ln_fact(N-1);
return(ans);
}
inline long long int fact_lli (const int& N)
{
long long int ans = 0;
if (N < 0) {
cerr << "Error: factorial of negative number. Exited." << endl;
exit(1);
}
else if ( N == 1 || N == 0) ans = 1;
else ans = fact_lli(N-1) * N;
return(ans);
}
inline long long int fact_ulli (const int& N)
{
unsigned long long int ans = 0;
if (N < 0) {
cerr << "Error: factorial of negative number. Exited." << endl;
exit(1);
}
else if ( N == 1 || N == 0) ans = 1;
else ans = fact_ulli(N-1) * N;
return(ans);
}
inline int choose (const int& N1, const int& N2)
{
// returns N1 choose N2
int ans = 0;
if (N1 < N2) {
cout << "Error: N1 smaller than N2 in choose. Exited." << endl;
exit(1);
}
else if (N1 == N2) ans = 1;
else if (N1 < 12) ans = fact(N1)/(fact(N2) * fact(N1 - N2));
else {
ans = 1;
int mult = N1;
while (mult > max(N2, N1 - N2)) ans *= mult--;
ans /= fact(min(N2, N1 - N2));
}
return(ans);
}
inline DP ln_choose (const int& N1, const int& N2)
{
// returns the log of N1 choose N2
DP ans = 0.0;
if (N1 < N2) {
cout << "Error: N1 smaller than N2 in choose. Exited." << endl;
exit(1);
}
else if (N1 == N2) ans = 0.0;
else ans = ln_fact(N1) - ln_fact(N2) - ln_fact(N1 - N2);
return(ans);
}
inline long long int choose_lli (const int& N1, const int& N2)
{
// returns N1 choose N2
long long int ans = 0;
if (N1 < N2) {
cout << "Error: N1 smaller than N2 in choose. Exited." << endl;
exit(1);
}
else if (N1 == N2) ans = 1;
else if (N1 < 12) ans = fact_lli(N1)/(fact_lli(N2) * fact_lli(N1 - N2));
else {
// Make sure that N2 is less than or equal to N1/2; if not, just switch...
int N2_min = min(N2, N1 - N2);
ans = 1;
for (int i = 0; i < N2_min; ++i) {
ans *= (N1 - i);
ans /= i + 1;
}
}
return(ans);
}
inline unsigned long long int choose_ulli (const int& N1, const int& N2)
{
// returns N1 choose N2
unsigned long long int ans = 0;
if (N1 < N2) {
cout << "Error: N1 smaller than N2 in choose. Exited." << endl;
exit(1);
}
else if (N1 == N2) ans = 1;
else if (N1 < 12) ans = fact_ulli(N1)/(fact_ulli(N2) * fact_ulli(N1 - N2));
else {
// Make sure that N2 is less than or equal to N1/2; if not, just switch...
int N2_min = min(N2, N1 - N2);
ans = 1;
for (int i = 0; i < N2_min; ++i) {
ans *= (N1 - i);
ans /= i + 1;
}
}
return(ans);
}
inline DP SIGN (const DP &a, const DP &b)
{
return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);
}
inline DP sign_of (const DP& a)
{
return (a >= 0.0 ? 1.0 : -1.0);
}
inline int sgn_int (const int& a)
{
return (a >= 0) ? 1 : -1;
}
inline int sgn_DP (const DP& a)
{
return (a >= 0) ? 1 : -1;
}
template<class T>
inline void SWAP (T& a, T& b) {T dum = a; a = b; b = dum;}
inline int kronecker (int a, int b)
{
return a == b ? 1 : 0;
}
template<class T>
inline bool is_nan (const T& a)
{
return(!((a < T(0.0)) || (a >= T(0.0))));
}
inline complex<DP> atan_cx(const complex<DP>& x)
{
return(-0.5 * II * log((1.0 + II* x)/(1.0 - II* x)));
}
/**************** Gamma function *******************/
inline complex<double> ln_Gamma (complex<double> z)
{
// Implementation of Lanczos method with g = 9.
// Coefficients from Godfrey 2001.
if (real(z) < 0.5) return(log(PI/(sin(PI*z))) - ln_Gamma(1.0 - z));
else {
complex<double> series = 1.000000000000000174663
+ 5716.400188274341379136/z
- 14815.30426768413909044/(z + 1.0)
+ 14291.49277657478554025/(z + 2.0)
- 6348.160217641458813289/(z + 3.0)
+ 1301.608286058321874105/(z + 4.0)
- 108.1767053514369634679/(z + 5.0)
+ 2.605696505611755827729/(z + 6.0)
- 0.7423452510201416151527e-2 / (z + 7.0)
+ 0.5384136432509564062961e-7 / (z + 8.0)
- 0.4023533141268236372067e-8 / (z + 9.0);
return(0.5 * logtwoPI + (z - 0.5) * log(z + 8.5) - (z + 8.5) + log(series));
}
return(log(0.0)); // never called
}
inline complex<double> ln_Gamma_old (complex<double> z)
{
// Implementation of Lanczos method with g = 9.
// Coefficients from Godfrey 2001.
if (real(z) < 0.5) return(log(PI/(sin(PI*z))) - ln_Gamma(1.0 - z));
else {
int g = 9;
double p[11] = { 1.000000000000000174663,
5716.400188274341379136,
-14815.30426768413909044,
14291.49277657478554025,
-6348.160217641458813289,
1301.608286058321874105,
-108.1767053514369634679,
2.605696505611755827729,
-0.7423452510201416151527e-2,
0.5384136432509564062961e-7,
-0.4023533141268236372067e-8 };
complex<double> z_min_1 = z - 1.0;
complex<double> series = p[0];
for (int i = 1; i < g+2; ++i)
series += p[i]/(z_min_1 + complex<double>(i));
return(0.5 * logtwoPI + (z_min_1 + 0.5) * log(z_min_1 + complex<double>(g) + 0.5) - (z_min_1 + complex<double>(g) + 0.5) + log(series));
}
return(log(0.0)); // never called
}
inline complex<double> ln_Gamma_2 (complex<double> z)
{
// Implementation of Lanczos method with g = 7.
if (real(z) < 0.5) return(log(PI/(sin(PI*z)) - ln_Gamma(1.0 - z)));
else {
int g = 7;
double p[9] = { 0.99999999999980993, 676.5203681218851, -1259.1392167224028,
771.32342877765313, -176.61502916214059, 12.507343278686905,
-0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7};
complex<double> z_min_1 = z - 1.0;
complex<double> series = p[0];
for (int i = 1; i < g+2; ++i)
series += p[i]/(z_min_1 + complex<double>(i));
return(0.5 * logtwoPI + (z_min_1 + 0.5) * log(z_min_1 + complex<double>(g) + 0.5) - (z_min_1 + complex<double>(g) + 0.5) + log(series));
}
return(log(0.0)); // never called
}
/********** Partition numbers **********/
inline long long int Partition_Function (int n)
{
// Returns the value of the partition function p(n), giving the number of partitions of n into integers.
if (n < 0) JSCerror("Calling Partition_Function for n < 0.");
else if (n == 0 || n == 1) return(1LL);
else if (n == 2) return(2LL);
else if (n == 3) return(3LL);
else { // do recursion using pentagonal numbers
long long int pn = 0LL;
int pentnrplus, pentnrmin; // pentagonal numbers
for (int i = 1; true; ++i) {
pentnrplus = (i * (3*i - 1))/2;
pentnrmin = (i * (3*i + 1))/2;
//cout << "\ti = " << i << "pnrp = " << pentnrplus << "\tpnrm = " << pentnrmin << endl;
if (n - pentnrplus >= 0) pn += (i % 2 ? 1LL : -1LL) * Partition_Function (n - pentnrplus);
if (n - pentnrmin >= 0) pn += (i % 2 ? 1LL : -1LL) * Partition_Function (n - pentnrmin);
else break;
}
return(pn);
}
return(-1LL); // never called
}
/********** Sorting **********/
/*
template<class item_type>
void QuickSort (item_type* a, int l, int r)
{
static item_type m;
static int j;
int i;
if (r > l) {
m = a[r]; i = l-1; j = r;
for (;;) {
while (a[++i] < m);
while (a[--j] > m);
if (i >= j) break;
std::swap(a[i], a[j]);
}
std::swap(a[i], a[r]);
QuickSort(a, l, i-1);
QuickSort(a, i+1, r);
}
}
*/
template <class T>
void QuickSort (T* V, int l, int r)
{
int i = l, j = r;
T pivot = V[l + (r-l)/2];
while (i <= j) {
while (V[i] < pivot) i++;
while (V[j] > pivot) j--;
if (i <= j) {
std::swap(V[i],V[j]);
i++;
j--;
}
};
if (l < j) QuickSort(V, l, j);
if (i < r) QuickSort(V, i, r);
}
/*
template<class item_type>
void QuickSort (item_type* a, int* idx, int l, int r)
{
static item_type m;
static int j;
int i;
if (r > l) {
m = a[r]; i = l-1; j = r;
for (;;) {
while (a[++i] < m);
while (a[--j] > m);
if (i >= j) break;
std::swap(a[i], a[j]);
std::swap(idx[i], idx[j]);
}
std::swap(a[i], a[r]);
std::swap(idx[i], idx[r]);
QuickSort(a, idx, l, i-1);
QuickSort(a, idx, i+1, r);
}
}
*/
template <class T>
void QuickSort (T* V, int* index, int l, int r)
{
int i = l, j = r;
T pivot = V[l + (r-l)/2];
while (i <= j) {
while (V[i] < pivot) i++;
while (V[j] > pivot) j--;
if (i <= j) {
std::swap(V[i],V[j]);
std::swap(index[i],index[j]);
i++;
j--;
}
};
if (l < j) QuickSort(V, index, l, j);
if (i < r) QuickSort(V, index, i, r);
}
} // namespace JSC
#endif // _JS_UTIL_H_