Import ABACUS++G_8 code; cleanup files; new README
This commit is contained in:
+122
@@ -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_
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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_
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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_
|
||||
Reference in New Issue
Block a user