Import ABACUS++G_8 code; cleanup files; new README
This commit is contained in:
parent
61084ef3b3
commit
103cbe84d6
|
@ -0,0 +1,9 @@
|
|||
.DS_Store
|
||||
|
||||
*~
|
||||
|
||||
*tar.gz
|
||||
|
||||
bin/*
|
||||
lib/*
|
||||
obj/*
|
|
@ -0,0 +1,492 @@
|
|||
#**********************************************************
|
||||
#
|
||||
# This software is part of J.-S. Caux's ABACUS++ library.
|
||||
#
|
||||
# Copyright (c).
|
||||
#
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
# File: Makefile
|
||||
#
|
||||
#
|
||||
#***********************************************************/
|
||||
|
||||
VERSION = ABACUS++G_8
|
||||
|
||||
# Base directory, tree of all source files, headers
|
||||
BASEDIR = #/Users/jcaux/WORK/ABACUS++/
|
||||
OBJDIR = $(BASEDIR)obj/
|
||||
HEADDIR = $(BASEDIR)include/
|
||||
LIBDIR = $(BASEDIR)lib/
|
||||
SRCDIR = $(BASEDIR)src/
|
||||
EXECSDIR = $(BASEDIR)src/EXECS/
|
||||
BINDIR = $(BASEDIR)bin/
|
||||
|
||||
#COMPILE = g++ -Wall -I$(BASEDIR)include/ -L$(LIBDIR) -O3 -stdlib=libstdc++
|
||||
#COMPILE = g++ -Wall -I$(BASEDIR)include/ -L$(LIBDIR) -O3
|
||||
COMPILE = g++ -I$(BASEDIR)include/ -L$(LIBDIR) -O3 -w -fopenmp
|
||||
#COMPILE_MPI = mpicxx -I$(BASEDIR)include/ -L$(LIBDIR) -O3 -stdlib=libstdc++
|
||||
COMPILE_MPI = mpicxx -I$(BASEDIR)include/ -L$(LIBDIR) -O3 -w -fopenmp
|
||||
#COMPILE_OMP = g++ -I$(BASEDIR)include/ -L$(LIBDIR) -O3 -w -fopenmp
|
||||
|
||||
VPATH = $(SRCDIR)BETHE:$(SRCDIR)LIEBLIN:$(SRCDIR)COMBI:$(SRCDIR)EXECS:$(SRCDIR)FITTING:$(SRCDIR)HEIS:$(SRCDIR)INTEG:$(SRCDIR)MATRIX:$(SRCDIR)NRG:$(SRCDIR)ODSLF:$(SRCDIR)SCAN:$(SRCDIR)TBA:$(SRCDIR)UTILS:$(SRCDIR)XXX_h0:$(SRCDIR)XXZ_h0:$(SRCDIR)YOUNG
|
||||
|
||||
vpath %.h $(HEADDIR)
|
||||
|
||||
#Headers_JSC = JSC.h JSC_util.h JSC_Bethe.h JSC_Combi.h JSC_Integ.h JSC_Matrix.h JSC_Scan.h JSC_Vect.h JSC_Young.h
|
||||
Headers_JSC = JSC.h JSC_util.h JSC_Combi.h JSC_Integ.h JSC_Matrix.h JSC_NRG.h JSC_Spec_Fns.h JSC_Vect.h JSC_Young.h
|
||||
#Headers_all = $(Headers_JSC) JSC_LiebLin.h JSC_Heis.h JSC_ODSLF.h JSC_Scan.h JSC_XXX_h0.h JSC_XXZ_h0.h
|
||||
Headers_all = $(Headers_JSC) JSC_LiebLin.h JSC_Heis.h JSC_Scan.h JSC_State_Ensemble.h JSC_XXX_h0.h JSC_XXZ_h0.h
|
||||
|
||||
#Objects_BETHE = $(OBJDIR)Bethe_State.o
|
||||
|
||||
Objects_LIEBLIN = $(OBJDIR)LiebLin_Bethe_State.o $(OBJDIR)LiebLin_Chem_Pot.o $(OBJDIR)LiebLin_Matrix_Element_Contrib.o $(OBJDIR)LiebLin_ln_Overlap.o $(OBJDIR)LiebLin_Sumrules.o $(OBJDIR)LiebLin_State_Ensemble.o \
|
||||
$(OBJDIR)LiebLin_Tgt0.o $(OBJDIR)LiebLin_Twisted_lnnorm.o $(OBJDIR)LiebLin_Twisted_ln_Overlap.o $(OBJDIR)LiebLin_Utils.o $(OBJDIR)ln_Density_ME.o $(OBJDIR)ln_Psi_ME.o $(OBJDIR)ln_g2_ME.o
|
||||
|
||||
Objects_HEIS = $(OBJDIR)Heis.o $(OBJDIR)Heis_Chem_Pot.o $(OBJDIR)Heis_Sumrules.o $(OBJDIR)Heis_Matrix_Element_Contrib.o \
|
||||
$(OBJDIR)ln_Overlap_XXX.o \
|
||||
$(OBJDIR)ln_Sz_ME_XXX.o $(OBJDIR)ln_Sz_ME_XXZ.o $(OBJDIR)ln_Sz_ME_XXZ_gpd.o \
|
||||
$(OBJDIR)ln_Smin_ME_XXX.o $(OBJDIR)ln_Smin_ME_XXZ.o $(OBJDIR)ln_Smin_ME_XXZ_gpd.o \
|
||||
$(OBJDIR)ln_Szz_ME_XXX.o $(OBJDIR)ln_Smm_ME_XXX.o $(OBJDIR)ln_Szm_p_Smz_ME_XXX.o \
|
||||
$(OBJDIR)M_vs_H.o \
|
||||
$(OBJDIR)XXX_Bethe_State.o $(OBJDIR)XXZ_Bethe_State.o $(OBJDIR)XXZ_gpd_Bethe_State.o
|
||||
|
||||
Objects_ODSLF = $(OBJDIR)ODSLF.o $(OBJDIR)ODSLF_Chem_Pot.o $(OBJDIR)ODSLF_Sumrules.o $(OBJDIR)ODSLF_XXZ_Bethe_State.o $(OBJDIR)ODSLF_Matrix_Element_Contrib.o \
|
||||
$(OBJDIR)ln_Sz_ME_ODSLF_XXZ.o $(OBJDIR)ln_Smin_ME_ODSLF_XXZ.o
|
||||
|
||||
Objects_COMBI = $(OBJDIR)Combinatorics.o
|
||||
|
||||
Objects_FITTING = $(OBJDIR)covsrt.o $(OBJDIR)lin_reg.o $(OBJDIR)mrq.o $(OBJDIR)polint.o $(OBJDIR)polint_cx.o
|
||||
|
||||
Objects_INTEG = $(OBJDIR)Integration.o
|
||||
|
||||
Objects_MATRIX = $(OBJDIR)balanc.o $(OBJDIR)det_LU.o $(OBJDIR)det_LU_CX.o $(OBJDIR)eigsrt.o $(OBJDIR)elmhes.o $(OBJDIR)gaussj.o $(OBJDIR)hqr.o \
|
||||
$(OBJDIR)jacobi.o $(OBJDIR)lndet_LU.o $(OBJDIR)lndet_LU_dstry.o $(OBJDIR)lndet_LU_CX.o $(OBJDIR)lndet_LU_CX_dstry.o $(OBJDIR)lubksb.o \
|
||||
$(OBJDIR)lubksb_CX.o $(OBJDIR)ludcmp.o $(OBJDIR)ludcmp_CX.o $(OBJDIR)pythag.o $(OBJDIR)tqli.o $(OBJDIR)tred2.o
|
||||
|
||||
Objects_NRG = $(OBJDIR)NRG_State_Selector.o $(OBJDIR)NRG_DME_Matrix_Block_builder.o $(OBJDIR)NRG_K_Weight_integrand.o
|
||||
|
||||
#Objects_SCAN = $(OBJDIR)Descendents.o $(OBJDIR)General_Scan.o $(OBJDIR)General_Scan_Parallel.o $(OBJDIR)Particle_Hole_Excitation_Cost.o $(OBJDIR)Scan_Info.o $(OBJDIR)Scan_Thread_List.o
|
||||
Objects_SCAN = $(OBJDIR)Descendents.o $(OBJDIR)General_Scan.o $(OBJDIR)General_Scan_Parallel.o $(OBJDIR)Particle_Hole_Excitation_Cost.o $(OBJDIR)Scan_Info.o $(OBJDIR)Scan_Thread_Data.o
|
||||
|
||||
Objects_TBA = $(OBJDIR)Root_Density.o $(OBJDIR)TBA_LiebLin.o $(OBJDIR)TBA_XXZ.o $(OBJDIR)TBA_2CBG.o
|
||||
|
||||
#Objects_UTILS = $(OBJDIR)Data_File_Name.o $(OBJDIR)K_and_Omega_Files.o $(OBJDIR)Smoothen_RAW_into_SF.o $(OBJDIR)Smoothen_RAW_into_SF_LiebLin_Scaled.o $(OBJDIR)Sort_RAW_File.o $(OBJDIR)State_Label.o
|
||||
Objects_UTILS = $(OBJDIR)Data_File_Name.o $(OBJDIR)K_and_Omega_Files.o $(OBJDIR)Smoothen_RAW_into_SF.o $(OBJDIR)Smoothen_RAW_into_SF_LiebLin_Scaled.o $(OBJDIR)Sort_RAW_File.o $(OBJDIR)State_Label.o
|
||||
|
||||
Objects_XXX_h0 = $(OBJDIR)XXX_h0.o
|
||||
|
||||
Objects_XXZ_h0 = $(OBJDIR)XXZ_h0.o
|
||||
|
||||
Objects_YOUNG = $(OBJDIR)Young_Tableau.o
|
||||
|
||||
#Objects_ALL = $(Objects_LIEBLIN) $(Objects_HEIS) $(Objects_COMBI) $(Objects_FITTING) $(Objects_INTEG) $(Objects_MATRIX) $(Objects_NRG) $(Objects_ODSLF) $(Objects_SCAN) $(Objects_TBA) $(Objects_UTILS) $(Objects_XXX_h0) $(Objects_XXZ_h0) $(Objects_YOUNG)
|
||||
Objects_ALL = $(Objects_LIEBLIN) $(Objects_HEIS) $(Objects_COMBI) $(Objects_FITTING) $(Objects_INTEG) $(Objects_MATRIX) $(Objects_NRG) $(Objects_SCAN) $(Objects_TBA) $(Objects_UTILS) $(Objects_XXX_h0) $(Objects_XXZ_h0) $(Objects_YOUNG)
|
||||
|
||||
#EXECS = $(BINDIR)LiebLin_DSF $(BINDIR)Smoothen_LiebLin_DSF $(BINDIR)Heis_DSF $(BINDIR)Smoothen_Heis_DSF $(BINDIR)Smoothen_Heis_ASF $(BINDIR)Check_RAW_File
|
||||
#EXECS = $(BINDIR)LiebLin_DSF $(BINDIR)LiebLin_DSF_tester $(BINDIR)Smoothen_LiebLin_DSF $(BINDIR)Smoothen_LiebLin_DSF_DiK $(BINDIR)Heis_DSF $(BINDIR)Smoothen_Heis_DSF $(BINDIR)Smoothen_Heis_ASF $(BINDIR)Check_RAW_File
|
||||
EXECS = $(BINDIR)LiebLin_DSF $(BINDIR)LiebLin_Data_Daemon $(BINDIR)LiebLin_RAW_File_Stats $(BINDIR)LiebLin_DSF_tester $(BINDIR)LiebLin_DSF_tester_Ix2 $(BINDIR)LiebLin_DSF_MosesState $(BINDIR)LiebLin_DSF_over_Ensemble $(BINDIR)Smoothen_LiebLin_DSF $(BINDIR)Heis_DSF $(BINDIR)Heis_DSF_GeneralState $(BINDIR)Smoothen_Heis_DSF $(BINDIR)Check_RAW_File
|
||||
|
||||
|
||||
##########################################
|
||||
# The library and the set of executables in bin/ are the ultimate targets
|
||||
|
||||
lib$(VERSION).a : $(Objects_ALL)
|
||||
ar -cru lib$(VERSION).a $(Objects_ALL)
|
||||
mv lib$(VERSION).a $(BASEDIR)lib/
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_DSF.cc -o $(BINDIR)LiebLin_DSF -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_Data_Daemon.cc -o $(BINDIR)LiebLin_Data_Daemon -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_Data_Daemon_Nscaling.cc -o $(BINDIR)LiebLin_Data_Daemon_Nscaling -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_Catalogue_Fixed_c_k_Nscaling.cc -o $(BINDIR)LiebLin_Catalogue_Fixed_c_k_Nscaling -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_RAW_File_Stats.cc -o $(BINDIR)LiebLin_RAW_File_Stats -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_DSF_GeneralState.cc -o $(BINDIR)LiebLin_DSF_GeneralState -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)LiebLin_DSF_MosesState.cc -o $(BINDIR)LiebLin_DSF_MosesState -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_DSF_over_Ensemble.cc -o $(BINDIR)LiebLin_DSF_over_Ensemble -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_DSF_tester.cc -o $(BINDIR)LiebLin_DSF_tester -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_DSF_tester_Ix2.cc -o $(BINDIR)LiebLin_DSF_tester_Ix2 -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)LiebLin_Moses_tester.cc -o $(BINDIR)LiebLin_Moses_tester -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF.cc -o $(BINDIR)Smoothen_LiebLin_DSF -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF_Scaled.cc -o $(BINDIR)Smoothen_LiebLin_DSF_Scaled -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF_over_Ensemble.cc -o $(BINDIR)Smoothen_LiebLin_DSF_over_Ensemble -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF_GeneralState.cc -o $(BINDIR)Smoothen_LiebLin_DSF_GeneralState -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF_MosesState.cc -o $(BINDIR)Smoothen_LiebLin_DSF_MosesState -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_TBA.cc -o $(BINDIR)LiebLin_TBA -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_TBA_fixed_nbar.cc -o $(BINDIR)LiebLin_TBA_fixed_nbar -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_TBA_fixed_nbar_ebar.cc -o $(BINDIR)LiebLin_TBA_fixed_nbar_ebar -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF_DiK.cc -o $(BINDIR)Smoothen_LiebLin_DSF_DiK -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)Smoothen_LiebLin_ASF.cc -o $(BINDIR)Smoothen_LiebLin_ASF -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)Heis_DSF.cc -o $(BINDIR)Heis_DSF -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)Heis_DSF_GeneralState.cc -o $(BINDIR)Heis_DSF_GeneralState -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)Smoothen_Heis_DSF.cc -o $(BINDIR)Smoothen_Heis_DSF -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)Smoothen_Heis_ASF.cc -o $(BINDIR)Smoothen_Heis_ASF -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)XXZ_gpd_StagSz_h0.cc -o $(BINDIR)XXZ_gpd_StagSz_h0 -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)ODSLF_DSF.cc -o $(BINDIR)ODSLF_DSF -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)Smoothen_ODSLF_DSF.cc -o $(BINDIR)Smoothen_ODSLF_DSF -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)Check_RAW_File.cc -o $(BINDIR)Check_RAW_File -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)Analyze_RAW_File.cc -o $(BINDIR)Analyze_RAW_File -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)RAW_File_Stats.cc -o $(BINDIR)RAW_File_Stats -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)Produce_Sorted_RAW_File.cc -o $(BINDIR)Produce_Sorted_RAW_File -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)2CBG_ThLim.cc -o $(BINDIR)2CBG_ThLim -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_Fourier_to_x_equal_t.cc -o $(BINDIR)LiebLin_Fourier_to_x_equal_t -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_Fourier_to_t_equal_x.cc -o $(BINDIR)LiebLin_Fourier_to_t_equal_x -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_Fourier_to_x_equal_t_from_RAW.cc -o $(BINDIR)LiebLin_Fourier_to_x_equal_t_from_RAW -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_Fourier_to_t_equal_x_from_RAW.cc -o $(BINDIR)LiebLin_Fourier_to_t_equal_x_from_RAW -l$(VERSION)
|
||||
$(COMPILE) $(EXECSDIR)LiebLin_Fourier_ssf_to_Qsqx.cc -o $(BINDIR)LiebLin_Fourier_ssf_to_Qsqx -l$(VERSION)
|
||||
|
||||
###########################################
|
||||
# Interacting LiebLin gas
|
||||
|
||||
$(OBJDIR)LiebLin_Bethe_State.o : LiebLin_Bethe_State.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)LiebLin_Chem_Pot.o : LiebLin_Chem_Pot.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)LiebLin_Matrix_Element_Contrib.o : LiebLin_Matrix_Element_Contrib.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)LiebLin_ln_Overlap.o : LiebLin_ln_Overlap.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)LiebLin_Sumrules.o : LiebLin_Sumrules.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)LiebLin_State_Ensemble.o : LiebLin_State_Ensemble.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)LiebLin_Tgt0.o : LiebLin_Tgt0.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)LiebLin_Twisted_lnnorm.o : LiebLin_Twisted_lnnorm.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)LiebLin_Utils.o : LiebLin_Utils.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Density_ME.o : ln_Density_ME.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)LiebLin_Twisted_ln_Overlap.o : LiebLin_Twisted_ln_Overlap.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Psi_ME.o : ln_Psi_ME.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_g2_ME.o : ln_g2_ME.cc $(Headers_JSC) JSC_LiebLin.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
|
||||
###########################################
|
||||
# Heisenberg chains
|
||||
|
||||
$(OBJDIR)Heis.o : Heis.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)Heis_Chem_Pot.o : Heis_Chem_Pot.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)Heis_Sumrules.o : Heis_Sumrules.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)Heis_Matrix_Element_Contrib.o : Heis_Matrix_Element_Contrib.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Overlap_XXX.o : ln_Overlap_XXX.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Sz_ME_XXX.o : ln_Sz_ME_XXX.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Szz_ME_XXX.o : ln_Szz_ME_XXX.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Smm_ME_XXX.o : ln_Smm_ME_XXX.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Szm_p_Smz_ME_XXX.o : ln_Szm_p_Smz_ME_XXX.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Sz_ME_XXZ.o : ln_Sz_ME_XXZ.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Sz_ME_XXZ_gpd.o : ln_Sz_ME_XXZ_gpd.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Smin_ME_XXX.o : ln_Smin_ME_XXX.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Smin_ME_XXZ.o : ln_Smin_ME_XXZ.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Smin_ME_XXZ_gpd.o : ln_Smin_ME_XXZ_gpd.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)M_vs_H.o : M_vs_H.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)XXX_Bethe_State.o : XXX_Bethe_State.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)XXZ_Bethe_State.o : XXZ_Bethe_State.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)XXZ_gpd_Bethe_State.o : XXZ_gpd_Bethe_State.cc $(Headers_JSC) JSC_Heis.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
|
||||
###########################################
|
||||
# One-d spinless fermions
|
||||
|
||||
$(OBJDIR)ODSLF.o : ODSLF.cc $(Headers_JSC) JSC_Heis.h JSC_ODSLF.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ODSLF_Chem_Pot.o : ODSLF_Chem_Pot.cc $(Headers_JSC) JSC_ODSLF.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ODSLF_Sumrules.o : ODSLF_Sumrules.cc $(Headers_JSC) JSC_ODSLF.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ODSLF_XXZ_Bethe_State.o : ODSLF_XXZ_Bethe_State.cc $(Headers_JSC) JSC_Heis.h JSC_ODSLF.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Smin_ME_ODSLF_XXZ.o : ln_Smin_ME_ODSLF_XXZ.cc $(Headers_JSC) JSC_ODSLF.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ln_Sz_ME_ODSLF_XXZ.o : ln_Sz_ME_ODSLF_XXZ.cc $(Headers_JSC) JSC_ODSLF.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ODSLF_Matrix_Element_Contrib.o : ODSLF_Matrix_Element_Contrib.cc $(Headers_JSC) JSC_ODSLF.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
|
||||
###########################################
|
||||
# Combinatorics functions
|
||||
|
||||
$(OBJDIR)Combinatorics.o : Combinatorics.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
###########################################
|
||||
# Integ functions
|
||||
|
||||
$(OBJDIR)Integration.o : Integration.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
###########################################
|
||||
# Fitting functions
|
||||
|
||||
$(OBJDIR)covsrt.o : covsrt.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)lin_reg.o : lin_reg.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)mrq.o : mrq.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)polint.o : polint.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)polint_cx.o : polint_cx.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
|
||||
###########################################
|
||||
# Matrix functions
|
||||
|
||||
$(OBJDIR)balanc.o : balanc.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)det_LU.o : det_LU.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)det_LU_CX.o : det_LU_CX.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)eigsrt.o : eigsrt.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)elmhes.o : elmhes.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)gaussj.o : gaussj.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)hqr.o : hqr.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)jacobi.o : jacobi.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)lndet_LU.o : lndet_LU.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)lndet_LU_CX.o : lndet_LU_CX.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)lndet_LU_dstry.o : lndet_LU_dstry.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)lndet_LU_CX_dstry.o : lndet_LU_CX_dstry.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)lubksb.o : lubksb.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)lubksb_CX.o : lubksb_CX.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ludcmp.o : ludcmp.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)ludcmp_CX.o : ludcmp_CX.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)pythag.o : pythag.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)tqli.o : tqli.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)tred2.o : tred2.cc $(Headers_JSC)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
|
||||
###########################################
|
||||
# NRG
|
||||
|
||||
$(OBJDIR)NRG_K_Weight_integrand.o : NRG_K_Weight_integrand.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)NRG_State_Selector.o : NRG_State_Selector.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)NRG_DME_Matrix_Block_builder.o : NRG_DME_Matrix_Block_builder.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
|
||||
###########################################
|
||||
# Scan
|
||||
|
||||
#$(OBJDIR)Base.o : Base.cc $(Headers_all)
|
||||
# $(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)Descendents.o : Descendents.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)General_Scan.o : General_Scan.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)General_Scan_Parallel.o : General_Scan_Parallel.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)Particle_Hole_Excitation_Cost.o : Particle_Hole_Excitation_Cost.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
#$(OBJDIR)Offsets.o : Offsets.cc $(Headers_all)
|
||||
# $(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)Scan_Info.o : Scan_Info.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
#$(OBJDIR)Scan_State_List.o : Scan_State_List.cc $(Headers_all)
|
||||
# $(COMPILE) -c $< -o $@
|
||||
|
||||
#$(OBJDIR)Scan_Thread_List.o : Scan_Thread_List.cc $(Headers_all)
|
||||
#$(OBJDIR)Scan_Thread_Set.o : Scan_Thread_Set.cc $(Headers_all)
|
||||
$(OBJDIR)Scan_Thread_Data.o : Scan_Thread_Data.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
###########################################
|
||||
# Thermodynamic Bethe Ansatz
|
||||
|
||||
$(OBJDIR)Root_Density.o : Root_Density.cc $(Headers_JSC) JSC_TBA.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)TBA_LiebLin.o : TBA_LiebLin.cc $(Headers_JSC) JSC_TBA.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)TBA_XXZ.o : TBA_XXZ.cc $(Headers_JSC) JSC_TBA.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)TBA_2CBG.o : TBA_2CBG.cc $(Headers_JSC) JSC_TBA.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
###########################################
|
||||
# Utilities
|
||||
|
||||
$(OBJDIR)Data_File_Name.o : Data_File_Name.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)K_and_Omega_Files.o : K_and_Omega_Files.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)Smoothen_RAW_into_SF.o : Smoothen_RAW_into_SF.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)Smoothen_RAW_into_SF_LiebLin_Scaled.o : Smoothen_RAW_into_SF_LiebLin_Scaled.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)Sort_RAW_File.o : Sort_RAW_File.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
$(OBJDIR)State_Label.o : State_Label.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
###########################################
|
||||
# XXX_h0
|
||||
|
||||
$(OBJDIR)XXX_h0.o : XXX_h0.cc $(Headers_all) JSC_XXX_h0.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
###########################################
|
||||
# XXZ_h0
|
||||
|
||||
$(OBJDIR)XXZ_h0.o : XXZ_h0.cc $(Headers_all) JSC_XXZ_h0.h
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
###########################################
|
||||
# Young Tableaux
|
||||
|
||||
$(OBJDIR)Young_Tableau.o : Young_Tableau.cc $(Headers_all)
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
|
||||
############################################
|
||||
|
||||
#executables :
|
||||
# $(COMPILE) $(EXECSDIR)LiebLin_DSF.cc -o $(BINDIR)LiebLin_DSF -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF.cc -o $(BINDIR)Smoothen_LiebLin_DSF -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)Heis_DSF.cc -o $(BINDIR)Heis_DSF -l$(VERSION)
|
||||
# $(COMPILE) $(EXECSDIR)Smoothen_Heis_DSF.cc -o $(BINDIR)Smoothen_Heis_DSF -l$(VERSION)
|
||||
|
||||
###########################################
|
||||
# Executables (parallel versions)
|
||||
|
||||
parallel :
|
||||
# $(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_par.cc -o $(BINDIR)LiebLin_DSF_par -l$(VERSION)
|
||||
$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_par_Prepare.cc -o $(BINDIR)LiebLin_DSF_par_Prepare -l$(VERSION)
|
||||
$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_par_Run.cc -o $(BINDIR)LiebLin_DSF_par_Run -l$(VERSION)
|
||||
$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_par_Wrapup.cc -o $(BINDIR)LiebLin_DSF_par_Wrapup -l$(VERSION)
|
||||
$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_GeneralState_par_Prepare.cc -o $(BINDIR)LiebLin_DSF_GeneralState_par_Prepare -l$(VERSION)
|
||||
$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_GeneralState_par_Run.cc -o $(BINDIR)LiebLin_DSF_GeneralState_par_Run -l$(VERSION)
|
||||
$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_GeneralState_par_Wrapup.cc -o $(BINDIR)LiebLin_DSF_GeneralState_par_Wrapup -l$(VERSION)
|
||||
# $(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_MosesState_par.cc -o $(BINDIR)LiebLin_DSF_MosesState_par -l$(VERSION)
|
||||
# $(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_MosesState_par_Prepare.cc -o $(BINDIR)LiebLin_DSF_MosesState_par_Prepare -l$(VERSION)
|
||||
# $(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_MosesState_par_Run.cc -o $(BINDIR)LiebLin_DSF_MosesState_par_Run -l$(VERSION)
|
||||
# $(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_MosesState_par_Wrapup.cc -o $(BINDIR)LiebLin_DSF_MosesState_par_Wrapup -l$(VERSION)
|
||||
# $(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_over_Ensemble_par.cc -o $(BINDIR)LiebLin_DSF_over_Ensemble_par -l$(VERSION)
|
||||
# $(COMPILE_MPI) $(EXECSDIR)Heis_DSF_par.cc -o $(BINDIR)Heis_DSF_par -l$(VERSION)
|
||||
$(COMPILE_MPI) $(EXECSDIR)Heis_DSF_par_Prepare.cc -o $(BINDIR)Heis_DSF_par_Prepare -l$(VERSION)
|
||||
$(COMPILE_MPI) $(EXECSDIR)Heis_DSF_par_Run.cc -o $(BINDIR)Heis_DSF_par_Run -l$(VERSION)
|
||||
$(COMPILE_MPI) $(EXECSDIR)Heis_DSF_par_Wrapup.cc -o $(BINDIR)Heis_DSF_par_Wrapup -l$(VERSION)
|
||||
|
||||
|
||||
###########################################
|
||||
# Cleanup
|
||||
|
||||
clean :
|
||||
/bin/rm -f $(Objects_ALL)
|
||||
/bin/rm -f $(LIBDIR)$(VERSION)
|
||||
/bin/rm -f $(EXECS)
|
||||
|
||||
|
233
README.md
233
README.md
|
@ -1,2 +1,235 @@
|
|||
# ABACUS
|
||||
|
||||
Copyright (c) J.-S. Caux
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
Previous versions
|
||||
=================
|
||||
|
||||
------------------------------------------------------------------
|
||||
## ABACUS++G_8 [started 2015 02 20] [published 2015 04 04]
|
||||
|
||||
Building up on ++G_7.
|
||||
|
||||
Objectives:
|
||||
|
||||
- facilitate use of OpenMP, by removing the recursive aspect of descending. DONE.
|
||||
|
||||
- improve memory use. DONE.
|
||||
Replace in-memory Scan_Thread_Set by on-disk Scan_Thread_Data.
|
||||
Uses Scan_Thread structure.
|
||||
|
||||
Features:
|
||||
- OpenMP is implemented.
|
||||
- Scanning on spin chains is now implemented.
|
||||
- Scan_Info's Nfull now contains the sub-Hilbert space dimension (for spin chains; type == double)
|
||||
- Added the .stat file in General_Scan, containing info about expected data value and actually obtained one
|
||||
- Timing is more strictly enforced, using OpenMP wtime().
|
||||
|
||||
Notes:
|
||||
- a first implementation using OpenMP is archived as ABACUS++G_8_v1.tar.gz package.
|
||||
|
||||
------------------------------------------------------------------
|
||||
ABACUS++G_7 [published 2015 01 17]
|
||||
|
||||
Building up on ++G_6.
|
||||
- Now using 15 types of descendents, enabling fixed iK scanning with increasing ph nrs.
|
||||
- Scan_Thread_List replaced by Scan_Thread_Set (to optimize performance and threads storage)
|
||||
|
||||
Works well for LiebLin, including at finite T.
|
||||
|
||||
TODO:
|
||||
- implement scanning for spin chains (scanning over bases still missing for generic AveragingState)
|
||||
|
||||
------------------------------------------------------------------
|
||||
ABACUS++G_6 [started 2015 01]
|
||||
|
||||
Simple scanning: iK stepped up, iK stepped down (from ++G_5).
|
||||
Fixed momentum scanning is thus implemented.
|
||||
|
||||
Version 6.0: [published 2015 01 16]
|
||||
- uses 8 types of descendents
|
||||
- Works well for LiebLin, including finite T.
|
||||
|
||||
Version 6.1: proto version of ++G_7
|
||||
- uses greater nr of descendents, 15, enforcing strict ph nr increase
|
||||
|
||||
------------------------------------------------------------------
|
||||
ABACUS++G_5 [started 2014 12 11] [abandoned 2015 01, except for version 5.0 (great for GS of LiebLin)]
|
||||
|
||||
Fundamental rewriting of scanning protocol.
|
||||
|
||||
Version 5.0 works very well for ground state correlations of Lieb-Liniger.
|
||||
Heis: still bugged.
|
||||
|
||||
------------------------------------------------------------------
|
||||
ABACUS++G_4 [started 2014 12 08] [abandoned 2014 12 11]
|
||||
|
||||
Nontrivial bug: descending with inner and outer skeletons does not always
|
||||
preserve number of p-h excitations. Fatal for large c in LiebLin.
|
||||
|
||||
- Descending with type 2: instead of summing over all new p and h positions,
|
||||
just put p and h as close to each other as possible.
|
||||
To implement this, added a new type of desc (4), where this distance is increased.
|
||||
|
||||
TODO:
|
||||
- For XXX: inclusion of infinite rapidities as genuine particle type
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
ABACUS++G_3 [started 2014 11 10] [closed 2014 12 08]
|
||||
|
||||
- Change of naming convention: LiebLin instead of Bose or 1DBG.
|
||||
- For LiebLin: changed rapidity naming convention: now lambdaoc, to make rescaling \lambda/c explicit
|
||||
- Improved small c algorithm for LiebLin
|
||||
- Fixed momentum scanning implemented using inner and outer skeleton logic
|
||||
|
||||
------------------------------------------------------------------
|
||||
ABACUS++G_2 [closed 2014 11 10]
|
||||
[2013 09 20]
|
||||
- Scanning is now automatically over remaining pair of excitations; facilitates fixed iK scans
|
||||
- Threads are now over states with NScan-2 particles, intermediate states then include all Nscan states fulfilling the momentum constraints
|
||||
- Scanning for spin chains implemented (general states; also parallel). Needs further testing. Seems to work for ground state.
|
||||
|
||||
------------------------------------------------------------------
|
||||
ABACUS++G_1.1
|
||||
|
||||
[2013 09 06]
|
||||
Changed parallel version for Bose:
|
||||
- supercycle time is now an argument to functions
|
||||
- split the 'Prepare', 'Run' and 'Wrapup' into separate executables
|
||||
- added the 'filenamesuffix' argument to parallel functions
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
ABACUS++G_1
|
||||
|
||||
New labelling and descending implemented for arbitrary states with strings, e.g. spin chains.
|
||||
|
||||
Descendents for an arbitrary state are now generated according to the following logic.
|
||||
|
||||
TO DO:
|
||||
Include string deviation value in Bethe_State objects and in RAW files. Form factors are always computed.
|
||||
|
||||
|
||||
[2013 08 25]
|
||||
Changed sum rules for LiebLin density-density: now using f-sumrule from iKmin to iKmax.
|
||||
|
||||
|
||||
Earlier notes for ABACUS++T:
|
||||
##############################################################
|
||||
|
||||
Notable changes from ABACUS++:
|
||||
|
||||
- The state labelling is now done with a single `string' label, detailing the base, nr of particle-hole excitations (as compared to a reference scan state) and Ix2 changes. The number of particle-hole excitations is therefore not limited anymore, and (for LiebLin) there is no upper momentum limit. See the src/State_Label.cc file for the implementation details.
|
||||
|
||||
- The state scanning procedure (i.e. the descendents logic) is now implemented solely at the level of the quantum numbers, following a recursive logic in which excitations are created at the right, then left Fermi boundary and allowed to propagate deeper outside/inside as the tree is climbed.
|
||||
|
||||
- Since the labelling and descending are now completely general, dynamical correlations not only on ground states but also on arbitrary excited states can be computed efficiently. This thus allows to deal with finite temperature correlations.
|
||||
|
||||
|
||||
##############################################################
|
||||
|
||||
IMPROVEMENTS YET TO BE IMPLEMENTED:
|
||||
|
||||
- Some form of binning to make very large runs possible.
|
||||
Possibility: post-processing of the .raw file, joining together contributions at given iK and (about) same energy into effective ones and saving those into a pre-defined matrix format.
|
||||
Difficulties: the size of the .raw file is of the order of the .thr one, which must be kept.
|
||||
|
||||
##############################################################
|
||||
|
||||
VERSIONS: NOTES
|
||||
|
||||
Important conventions:
|
||||
|
||||
- Versions are numbered with two integers, [VERSION].[SUBVERSION]
|
||||
- Changes in subversion number indicate `internal' revisions which do not change any of the external conventions, data file structures, etc. Data produced with version V.S can be `polished' with version V.S' with S' != S.
|
||||
- Changes in version number indicate a larger scale revision affecting the conventions. Data produced with earlier versions are then deprecated.
|
||||
|
||||
---------------------------------------------------------------
|
||||
|
||||
ABACUS++T_1.0 [published 23 June 2011]
|
||||
|
||||
First version of new setup and logic for ABACUS. Implementation of all basic new ideas for state labelling and descending.
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
ABACUS++T_2.0 [in progress][*ABANDONED*]
|
||||
|
||||
Attempt at implementing fixed-momentum-based scanning.
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
ABACUS++T_3.0 [published 1 Nov 2011]
|
||||
|
||||
New, simpler logic for descendents: the hole positions are scanned immediately
|
||||
upon creation of a new particle-hole pair; the hole positions are then kept fixed
|
||||
in subsequent descending.
|
||||
|
||||
Problems:
|
||||
- when scanning for a function such as the one-body function for Lieb-Liniger,
|
||||
the extra particle in the AveragingState is not scanned to. Version 4 will
|
||||
address this problem.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
ABACUS++T_4.0 [published 1 Nov 2011]
|
||||
|
||||
Modification to the labeling logic:
|
||||
states are now always labeled using the AveragingState's quantum numbers,
|
||||
even if their bases are different. The form of the State_Label is thus changed.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
ABACUS++T_5.0 [published 4 Nov 2011]
|
||||
|
||||
Introduced two types of threads, separating scanning over fixed particle-hole numbers
|
||||
and adding a p-h.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
ABACUS++T_6.0 [published 21 Nov 2011]
|
||||
|
||||
The scanning is now also done over the hole positions.
|
||||
Upon the creation of a particle-hole, only hole positions at the edges of
|
||||
blocks of contiguous Ix2 in OriginState are used.
|
||||
The holes are then scanned moving towards the center of the blocks.
|
||||
|
||||
There are now thus 3 types of scanning:
|
||||
0: over holes
|
||||
1: over particles
|
||||
2: adding a p-h pair
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
ABACUS++T_7.0 [published 1 Dec 2011]]
|
||||
|
||||
Optimization of runtime memory use and of output files sizes.
|
||||
|
||||
Labels: introduction of compressed labels (used in raw and thr files).
|
||||
Removed conv boolean from raw file (all states in this file have converged).
|
||||
Threads: removed omega and iK (changed General_Scan accordingly), use compressed labels.
|
||||
|
||||
Scanning function: it's now possible to give a default file name when invoking
|
||||
General_Scan (and thus Scan_Bose, etc). This is done to avoid stupidly long file
|
||||
names when calculating correlators over AveragingStates which are far from
|
||||
the ground state.
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
ABACUS++T_8.0
|
||||
|
||||
Changed labels slightly, to avoid identifying empty string with integer 0.
|
||||
All labels with at least one excitation are now strictly nonempty.
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
ABACUS++T_9 [in development][abandoned]
|
||||
|
||||
Scanning over ensembles.
|
||||
|
|
|
@ -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
|
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_
|
|
@ -0,0 +1,307 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/BETHE/Base.cc
|
||||
|
||||
Purpose: defines functions in Base class,
|
||||
providing a unified base object for all
|
||||
Bethe Ansatz integrable models.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// Function definitions: class Base
|
||||
|
||||
Base::Base () : Charge(0), Nrap(Vect<int>()), Nraptot(0), Ix2_infty(Vect<DP>()),
|
||||
Ix2_max(Vect<int>()), id(0LL) {}
|
||||
|
||||
Base::Base (int N) : Charge(N), Nrap(Vect<int>(N,1)), Nraptot(N), Ix2_infty(Vect<DP>(1.0e+100,1)),
|
||||
Ix2_max(Vect<int>(LONG_LONG_MAX, 1)), id(N) {}
|
||||
|
||||
Base::Base (const Base& RefBase) // copy constructor
|
||||
: Charge(RefBase.Charge), Nrap(Vect<int>(RefBase.Nrap.size())), Nraptot(RefBase.Nraptot),
|
||||
Ix2_infty(Vect<DP>(RefBase.Ix2_infty.size())), Ix2_max(Vect<int>(RefBase.Ix2_max.size())), id(RefBase.id)
|
||||
{
|
||||
for (int i = 0; i < Nrap.size(); ++i) {
|
||||
Nrap[i] = RefBase.Nrap[i];
|
||||
Ix2_infty[i] = RefBase.Ix2_infty[i];
|
||||
Ix2_max[i] = RefBase.Ix2_max[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// DEPRECATED
|
||||
Base::Base (const Heis_Chain& RefChain, int M)
|
||||
: Charge(M), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings))
|
||||
{
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) Nrap[i] = 0;
|
||||
Nrap[0] = M;
|
||||
|
||||
Nraptot = 0;
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
|
||||
|
||||
// The id of this is zero by definition
|
||||
id = 0LL;
|
||||
|
||||
// Now compute the Ix2_infty numbers
|
||||
|
||||
(*this).Compute_Ix2_limits(RefChain);
|
||||
|
||||
}
|
||||
*/
|
||||
Base::Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities)
|
||||
: Charge(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)),
|
||||
id (0LL)
|
||||
{
|
||||
|
||||
// Check consistency of Nrapidities vector with RefChain
|
||||
|
||||
//if (RefChain.Nstrings != Nrapidities.size()) cout << "error: Nstrings = " << RefChain.Nstrings << "\tNrap.size = " << Nrapidities.size() << endl;
|
||||
|
||||
if (RefChain.Nstrings != Nrapidities.size()) JSCerror("Incompatible Nrapidities vector used in Base constructor.");
|
||||
|
||||
int Mcheck = 0;
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
|
||||
Charge = Mcheck;
|
||||
|
||||
Nraptot = 0;
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
|
||||
|
||||
// Compute id
|
||||
id += Nrapidities[0];
|
||||
long long int factor = 100000LL;
|
||||
for (int i = 1; i < RefChain.Nstrings; ++i) {
|
||||
id += factor * Nrapidities[i];
|
||||
factor *= 100LL;
|
||||
}
|
||||
|
||||
// Now compute the Ix2_infty numbers
|
||||
|
||||
(*this).Compute_Ix2_limits(RefChain);
|
||||
|
||||
}
|
||||
|
||||
Base::Base (const Heis_Chain& RefChain, long long int id_ref)
|
||||
: Charge(0), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)),
|
||||
id (id_ref)
|
||||
{
|
||||
// Build Nrapidities vector from id_ref
|
||||
|
||||
long long int factor = pow_ulli (10LL, 2* RefChain.Nstrings + 1);
|
||||
long long int id_eff = id_ref;
|
||||
for (int i = 0; i < RefChain.Nstrings - 1; ++i) {
|
||||
Nrap[RefChain.Nstrings - 1 - i] = id_eff/factor;
|
||||
id_eff -= factor * Nrap[RefChain.Nstrings - 1 - i];
|
||||
factor /= 100LL;
|
||||
}
|
||||
Nrap[0] = id_eff;
|
||||
|
||||
//id = id_ref;
|
||||
|
||||
//cout << "In Base constructor: id_ref = " << id_ref << " and Nrapidities = " << Nrap << endl;
|
||||
|
||||
// Check consistency of Nrapidities vector with RefChain
|
||||
|
||||
//if (RefChain.Nstrings != Nrap.size()) JSCerror("Incompatible Nrapidities vector used in Base constructor.");
|
||||
|
||||
int Mcheck = 0;
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
|
||||
Charge = Mcheck;
|
||||
|
||||
Nraptot = 0;
|
||||
for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
|
||||
|
||||
// Now compute the Ix2_infty numbers
|
||||
|
||||
(*this).Compute_Ix2_limits(RefChain);
|
||||
}
|
||||
|
||||
|
||||
Base& Base::operator= (const Base& RefBase)
|
||||
{
|
||||
if (this != & RefBase) {
|
||||
Charge = RefBase.Charge;
|
||||
Nrap = RefBase.Nrap;
|
||||
Nraptot = RefBase.Nraptot;
|
||||
Ix2_infty = RefBase.Ix2_infty;
|
||||
Ix2_max = RefBase.Ix2_max;
|
||||
id = RefBase.id;
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
bool Base::operator== (const Base& RefBase)
|
||||
{
|
||||
bool answer = (Nrap == RefBase.Nrap);
|
||||
|
||||
return (answer);
|
||||
}
|
||||
|
||||
bool Base::operator!= (const Base& RefBase)
|
||||
{
|
||||
bool answer = (Nrap != RefBase.Nrap);
|
||||
|
||||
return (answer);
|
||||
}
|
||||
|
||||
void Base::Compute_Ix2_limits (const Heis_Chain& RefChain)
|
||||
{
|
||||
|
||||
if ((RefChain.Delta > 0.0) && (RefChain.Delta < 1.0)) {
|
||||
|
||||
// Compute the Ix2_infty numbers
|
||||
|
||||
DP sum1 = 0.0;
|
||||
DP sum2 = 0.0;
|
||||
|
||||
for (int j = 0; j < RefChain.Nstrings; ++j) {
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
for (int k = 0; k < RefChain.Nstrings; ++k) {
|
||||
|
||||
sum2 = 0.0;
|
||||
|
||||
sum2 += (RefChain.Str_L[j] == RefChain.Str_L[k]) ? 0.0 : 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k])
|
||||
- 0.5 * fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) * RefChain.anis));
|
||||
sum2 += 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k])
|
||||
- 0.5 * (RefChain.Str_L[j] + RefChain.Str_L[k]) * RefChain.anis));
|
||||
|
||||
for (int a = 1; a < JSC::min(RefChain.Str_L[j], RefChain.Str_L[k]); ++a)
|
||||
sum2 += 2.0 * 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k])
|
||||
- 0.5 * (fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) + 2.0*a) * RefChain.anis));
|
||||
|
||||
sum1 += (Nrap[k] - ((j == k) ? 1 : 0)) * sum2;
|
||||
}
|
||||
|
||||
Ix2_infty[j] = (1.0/PI) * fabs(RefChain.Nsites * 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j])
|
||||
- 0.5 * RefChain.Str_L[j] * RefChain.anis)) - sum1);
|
||||
|
||||
} // The Ix2_infty are now set.
|
||||
|
||||
// Now compute the Ix2_max limits
|
||||
|
||||
for (int j = 0; j < RefChain.Nstrings; ++j) {
|
||||
|
||||
Ix2_max[j] = int(floor(Ix2_infty[j])); // sets basic integer
|
||||
|
||||
// Reject formally infinite rapidities (i.e. if Delta is root of unity)
|
||||
|
||||
//cout << "Ix2_infty - Ix2_max = " << Ix2_infty[j] - Ix2_max[j] << endl;
|
||||
//if (Ix2_infty[j] == Ix2_max[j]) {
|
||||
//Ix2_max[j] -= 2;
|
||||
//}
|
||||
// If Nrap is even, Ix2_max must be odd. If odd, then even.
|
||||
|
||||
if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1;
|
||||
|
||||
while (Ix2_max[j] > RefChain.Nsites) {
|
||||
Ix2_max[j] -= 2;
|
||||
}
|
||||
}
|
||||
} // if XXZ gapless
|
||||
|
||||
else if (RefChain.Delta == 1.0) {
|
||||
|
||||
// Compute the Ix2_infty numbers
|
||||
|
||||
int sum1 = 0;
|
||||
|
||||
for (int j = 0; j < RefChain.Nstrings; ++j) {
|
||||
|
||||
sum1 = 0;
|
||||
|
||||
for (int k = 0; k < RefChain.Nstrings; ++k) {
|
||||
|
||||
sum1 += Nrap[k] * (2 * JSC::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0));
|
||||
}
|
||||
|
||||
//Ix2_infty[j] = (RefChain.Nsites - 1.0 + 2.0 * RefChain.Str_L[j] - sum1);
|
||||
Ix2_infty[j] = (RefChain.Nsites + 1.0 - sum1); // to get counting right...
|
||||
|
||||
} // The Ix2_infty are now set.
|
||||
|
||||
// Now compute the Ix2_max limits
|
||||
|
||||
for (int j = 0; j < RefChain.Nstrings; ++j) {
|
||||
|
||||
Ix2_max[j] = int(floor(Ix2_infty[j])); // sets basic integer
|
||||
|
||||
// Give the correct parity to Ix2_max
|
||||
|
||||
// If Nrap is even, Ix2_max must be odd. If odd, then even.
|
||||
|
||||
if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1;
|
||||
|
||||
// If Ix2_max equals Ix2_infty, we reduce it by 2:
|
||||
|
||||
if (Ix2_max[j] == int(Ix2_infty[j])) Ix2_max[j] -= 2;
|
||||
|
||||
while (Ix2_max[j] > RefChain.Nsites) {
|
||||
Ix2_max[j] -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
} // if XXX AFM
|
||||
|
||||
else if (RefChain.Delta > 1.0) {
|
||||
|
||||
// Compute the Ix2_infty numbers
|
||||
|
||||
int sum1 = 0;
|
||||
|
||||
for (int j = 0; j < RefChain.Nstrings; ++j) {
|
||||
|
||||
sum1 = 0;
|
||||
|
||||
for (int k = 0; k < RefChain.Nstrings; ++k) {
|
||||
|
||||
sum1 += Nrap[k] * (2 * JSC::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0));
|
||||
}
|
||||
|
||||
Ix2_infty[j] = (RefChain.Nsites - 1 + 2 * RefChain.Str_L[j] - sum1);
|
||||
|
||||
} // The Ix2_infty are now set.
|
||||
|
||||
// Now compute the Ix2_max limits
|
||||
|
||||
for (int j = 0; j < RefChain.Nstrings; ++j) {
|
||||
|
||||
Ix2_max[j] = int(floor(Ix2_infty[j])); // sets basic integer
|
||||
|
||||
// Give the correct parity to Ix2_max
|
||||
|
||||
// If Nrap is even, Ix2_max must be odd. If odd, then even.
|
||||
|
||||
if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1;
|
||||
|
||||
// If Ix2_max equals Ix2_infty, we reduce it by 2:
|
||||
|
||||
//if (Ix2_max[j] == Ix2_infty[j]) Ix2_max[j] -= 2;
|
||||
|
||||
while (Ix2_max[j] > RefChain.Nsites) {
|
||||
Ix2_max[j] -= 2;
|
||||
}
|
||||
|
||||
// Fudge, for strings:
|
||||
//if (RefChain.Str_L[j] >= 1) Ix2_max[j] += 2;
|
||||
//Ix2_max[j] += 2;
|
||||
}
|
||||
|
||||
} // if XXZ_gpd
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,29 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/BETHE/Bethe_State.cc
|
||||
|
||||
Purpose: defines functions in Bethe_State class,
|
||||
providing a unified object for eigenstates of all
|
||||
Bethe Ansatz integrable models.
|
||||
|
||||
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
Bethe_State::Bethe_State (long long int base_id_ref, long long int type_id_ref, long long int id_ref, long long int maxid_ref) :
|
||||
base_id(base_id_ref), type_id(type_id_ref), id(id_ref), maxid(maxid_ref) {}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,277 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c) 2006-9.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/BETHE/Offsets.cc
|
||||
|
||||
Purpose: defines functions in Offsets class.
|
||||
|
||||
|
||||
Last modified: 19/10/2009
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// Function definitions: class Offsets
|
||||
|
||||
Offsets::Offsets () : base(), Tableau(Vect<Young_Tableau>()), type_id(0LL), id(0LL), maxid(0LL) {};
|
||||
|
||||
Offsets::Offsets (const Offsets& RefOffset) // copy constructor
|
||||
: base(RefOffset.base), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)), type_id(RefOffset.type_id), id(RefOffset.id), maxid(RefOffset.maxid)
|
||||
{
|
||||
for (int i = 0; i < 2 * base.Nrap.size() + 2; ++i) Tableau[i] = RefOffset.Tableau[i];
|
||||
}
|
||||
|
||||
Offsets::Offsets (const Heis_Base& RefBase, long long int req_type_id)
|
||||
// sets all tableaux to empty ones, with nparticles(req_type_id) at each level
|
||||
{
|
||||
// Build nparticles vector from req_type_id
|
||||
|
||||
Vect<int> nparticles(0, 2* RefBase.Nrap.size() + 2);
|
||||
long long int factor = pow_ulli (10LL, nparticles.size() - 1);
|
||||
long long int id_eff = req_type_id;
|
||||
for (int i = 0; i < nparticles.size(); ++i) {
|
||||
nparticles[nparticles.size() - 1 - i] = id_eff/factor;
|
||||
id_eff -= factor * nparticles[nparticles.size() - 1 - i];
|
||||
factor /= 10LL;
|
||||
}
|
||||
|
||||
// Check if we've got the right vector...
|
||||
long long int idcheck = Offsets_type_id (nparticles);
|
||||
if (idcheck != req_type_id) JSCerror("idcheck != req_type_id in Offsets constructor.");
|
||||
|
||||
(*this) = Offsets(RefBase, nparticles);
|
||||
}
|
||||
|
||||
Offsets::Offsets (const Heis_Base& RefBase, Vect<int> nparticles) // sets all tableaux to empty ones, with nparticles at each level
|
||||
: base(RefBase), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)), type_id(Offsets_type_id (nparticles)), id(0LL), maxid(0LL)
|
||||
{
|
||||
|
||||
// Checks on nparticles vector:
|
||||
|
||||
if (nparticles.size() != 2 * base.Nrap.size() + 2) JSCerror("Wrong nparticles.size in Offsets constructor.");
|
||||
|
||||
//if (base.Nrap[0] != (nparticles[3] + nparticles[2] + base.Mdown - nparticles[0] - nparticles[1])) JSCerror("Wrong Nrap[0] in Offsets constructor.");
|
||||
if (nparticles[3] + nparticles[2] != nparticles[0] + nparticles[1]) {
|
||||
cout << nparticles[0] << "\t" << nparticles[1] << "\t" << nparticles[2] << "\t" << nparticles[3] << endl;
|
||||
JSCerror("Wrong Npar[0-3] in Offsets constructor.");
|
||||
}
|
||||
|
||||
for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
|
||||
if (base.Nrap[base_level] != nparticles[2*base_level + 2] + nparticles[2*base_level + 3]) {
|
||||
cout << base_level << "\t" << base.Nrap[base_level] << "\t" << nparticles[2*base_level + 2] << "\t" << nparticles[2*base_level + 3] << endl;
|
||||
JSCerror("Wrong Nrap[] in Offsets constructor.");
|
||||
}
|
||||
|
||||
// nparticles[0,1]: number of holes on R and L side in GS interval
|
||||
if (nparticles[0] > (base.Nrap[0] + 1)/2) JSCerror("nparticles[0] too large in Offsets constructor.");
|
||||
if (nparticles[1] > base.Nrap[0]/2) JSCerror("nparticles[1] too large in Offsets constructor.");
|
||||
|
||||
// nparticles[2,3]: number of particles of type 0 on R and L side out of GS interval
|
||||
if (nparticles[2] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) JSCerror("nparticles[2] too large in Offsets constructor.");
|
||||
if (nparticles[3] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) JSCerror("nparticles[3] too large in Offsets constructor.");
|
||||
|
||||
for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
|
||||
if ((nparticles[2*base_level + 2] > 0 && nparticles[2*base_level + 2] > (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
|
||||
//|| (nparticles[2*base_level + 3] > 0 && nparticles[2*base_level + 3] > (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2)) {
|
||||
|| (nparticles[2*base_level + 3] > 0
|
||||
&& nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)) {
|
||||
cout << base_level << "\t" << nparticles[2*base_level + 2] << "\t" << (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2
|
||||
<< "\t" << nparticles[2*base_level + 3] << "\t" << (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2
|
||||
<< "\t" << (nparticles[2*base_level + 2] > 0) << "\t" << (nparticles[2*base_level + 2] > (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
|
||||
//<< "\t" << (nparticles[2*base_level + 3] > 0) << "\t" << (nparticles[2*base_level + 3] > (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2)
|
||||
<< "\t" << (nparticles[2*base_level + 3] > 0) << "\t"
|
||||
<< (nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
|
||||
<< endl;
|
||||
JSCerror("nparticles too large in Offsets constructor.");
|
||||
}
|
||||
|
||||
// Check sum of rapidities
|
||||
|
||||
// Holes in GS interval
|
||||
Tableau[0] = Young_Tableau(nparticles[0], (base.Nrap[0] + 1)/2 - nparticles[0]);
|
||||
Tableau[1] = Young_Tableau(nparticles[1], base.Nrap[0]/2 - nparticles[1], Tableau[0]);
|
||||
|
||||
// Particles of type 0 out of GS interval
|
||||
Tableau[2] = Young_Tableau(nparticles[2], (base.Ix2_max[0] - base.Nrap[0] + 1)/2 - nparticles[2], Tableau[0]);
|
||||
Tableau[3] = Young_Tableau(nparticles[3], (base.Ix2_max[0] - base.Nrap[0] + 1)/2 - nparticles[3], Tableau[2]);
|
||||
|
||||
// Tableaux of index i = 2,...: data about string type i/2-1.
|
||||
for (int base_level = 1; base_level < base.Nrap.size(); ++base_level) {
|
||||
Tableau[2*base_level + 2] = Young_Tableau(nparticles[2*base_level + 2],
|
||||
//(base.Ix2_max[base_level] - ((base.Nrap[base_level]) % 2) + 2)/2 - nparticles[2*base_level + 2], Tableau[2]);
|
||||
//(base.Ix2_max[base_level] - base.Nrap[base_level] % 2 + 2)/2 - nparticles[2*base_level + 2], Tableau[2]);
|
||||
(base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2))/2 + 1 - nparticles[2*base_level + 2], Tableau[2]);
|
||||
Tableau[2*base_level + 3] = Young_Tableau(nparticles[2*base_level + 3],
|
||||
//(base.Ix2_max[base_level] - base.Nrap[base_level] % 2)/2 - nparticles[2*base_level + 3], Tableau[3]);
|
||||
(base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2 + 1 - nparticles[2*base_level + 3], Tableau[3]);
|
||||
}
|
||||
|
||||
maxid = 1LL;
|
||||
//id = Tableau[0].id;
|
||||
for (int i = 0; i < nparticles.size(); ++i) {
|
||||
maxid *= Tableau[i].maxid + 1LL;
|
||||
//id += maxid + Tableau[i].id;
|
||||
}
|
||||
maxid -= 1LL;
|
||||
|
||||
}
|
||||
|
||||
Offsets& Offsets::operator= (const Offsets& RefOffset)
|
||||
{
|
||||
if (this != &RefOffset) {
|
||||
base = RefOffset.base;
|
||||
Tableau = RefOffset.Tableau;
|
||||
type_id = RefOffset.type_id;
|
||||
id = RefOffset.id;
|
||||
maxid = RefOffset.maxid;
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
bool Offsets::operator<= (const Offsets& RefOffsets)
|
||||
{
|
||||
// Check whether all nonzero tableau row lengths in RefOffsets
|
||||
// are <= than those in *this
|
||||
|
||||
bool answer = true;
|
||||
for (int level = 0; level < 4; ++level) { // check fundamental level only
|
||||
//for (int level = 0; level < 2 * base.Nrap.size() + 2; ++level) {
|
||||
// First check whether all rows which exist in both tableaux satisfy rule:
|
||||
for (int tableau_level = 0; tableau_level < JSC::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
|
||||
if (Tableau[level].Row_L[tableau_level] > RefOffsets.Tableau[level].Row_L[tableau_level])
|
||||
answer = false;
|
||||
// Now check whether there exist extra rows violating rule:
|
||||
for (int tableau_level = JSC::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); tableau_level < Tableau[level].Nrows; ++tableau_level)
|
||||
if (Tableau[level].Row_L[tableau_level] > 0) answer = false;
|
||||
}
|
||||
|
||||
return(answer);
|
||||
}
|
||||
|
||||
bool Offsets::operator>= (const Offsets& RefOffsets)
|
||||
{
|
||||
// Check whether all nonzero tableau row lengths in RefOffsets
|
||||
// are >= than those in *this
|
||||
|
||||
bool answer = true;
|
||||
for (int level = 0; level < 4; ++level) { // check fundamental level only
|
||||
//for (int level = 0; level < 2 * base.Nrap.size() + 2; ++level) {
|
||||
// First check whether all rows which exist in both tableaux satisfy rule:
|
||||
for (int tableau_level = 0; tableau_level < JSC::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
|
||||
if (Tableau[level].Row_L[tableau_level] < RefOffsets.Tableau[level].Row_L[tableau_level])
|
||||
answer = false;
|
||||
// Now check whether there exist extra rows violating rule:
|
||||
for (int tableau_level = JSC::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); tableau_level < RefOffsets.Tableau[level].Nrows; ++tableau_level)
|
||||
if (RefOffsets.Tableau[level].Row_L[tableau_level] > 0) answer = false;
|
||||
}
|
||||
|
||||
return(answer);
|
||||
}
|
||||
|
||||
void Offsets::Compute_type_id ()
|
||||
{
|
||||
type_id = 0LL;
|
||||
|
||||
for (int i = 0; i < 2*base.Nrap.size() + 2; ++i) {
|
||||
Tableau[i].Compute_id();
|
||||
type_id += Tableau[i].Nrows * pow_ulli(10LL, i);
|
||||
}
|
||||
}
|
||||
|
||||
void Offsets::Set_to_id (long long int idnr)
|
||||
{
|
||||
// The idnr of the Offset is given by
|
||||
// sub_id[0] + (total number of tableaux of type 0) * (sub_id[1] + (total number of tableaux of type 1) * (sub_id[2] + ...
|
||||
// + total number of tableaux of type (2*base.Nrap.size()) * sub_id[2*base.Nrap.size() + 1]
|
||||
|
||||
if (idnr > maxid) {
|
||||
cout << idnr << "\t" << maxid << endl;
|
||||
JSCerror("idnr too large in offsets.Set_to_id.");
|
||||
}
|
||||
|
||||
id = idnr;
|
||||
|
||||
Vect<long long int> sub_id(0LL, 2*base.Nrap.size() + 2);
|
||||
|
||||
long long int idnr_eff = idnr;
|
||||
long long int temp_prod = 1LL;
|
||||
|
||||
Vect<long long int> result_choose(2*base.Nrap.size() + 2);
|
||||
|
||||
for (int i = 0; i <= 2*base.Nrap.size(); ++i) {
|
||||
//result_choose[i] = choose_lli(Tableau[i].Nrows + Tableau[i].Ncols, Tableau[i].Nrows);
|
||||
result_choose[i] = Tableau[i].maxid + 1LL;
|
||||
temp_prod *= result_choose[i];
|
||||
}
|
||||
|
||||
for (int i = 2*base.Nrap.size() + 1; i > 0; --i) {
|
||||
sub_id[i] = idnr_eff/temp_prod;
|
||||
idnr_eff -= sub_id[i] * temp_prod;
|
||||
temp_prod /= result_choose[i-1];
|
||||
}
|
||||
sub_id[0] = idnr_eff; // what's left goes to the bottom...
|
||||
|
||||
for (int i = 0; i <= 2*base.Nrap.size() + 1; ++i) {
|
||||
//cout << "level = " << i << " Tableau.id = " << sub_id[i] << endl;
|
||||
if ((Tableau[i].Nrows * Tableau[i].Ncols == 0) && (sub_id[i] != 0)) JSCerror("index too large in offset.Set_to_id.");
|
||||
if (Tableau[i].id != sub_id[i]) Tableau[i].Set_to_id(sub_id[i]);
|
||||
}
|
||||
|
||||
Compute_type_id ();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Offsets::Compute_id ()
|
||||
{
|
||||
long long int prod_maxid = 1LL;
|
||||
|
||||
id = 0LL;
|
||||
|
||||
for (int i = 0; i < 2*base.Nrap.size() + 2; ++i) {
|
||||
Tableau[i].Compute_id();
|
||||
id += Tableau[i].id * prod_maxid;
|
||||
prod_maxid *= Tableau[i].maxid + 1LL;
|
||||
}
|
||||
}
|
||||
|
||||
Vect<long long int> Offsets::Descendents (bool fixed_iK)
|
||||
{
|
||||
// From a given vector of Young tableaux specifying a particular eigenstate,
|
||||
// this function provides the full set of descendents (either at the same momentum if
|
||||
// fixed_iK == true, or not) by returning a vector of all descendent id's (leaving the
|
||||
// base and type invariant), which can then be used for further calculations.
|
||||
|
||||
// This set of descendents is meant to be used when calculating either partition functions
|
||||
// or zero-temperature correlation functions.
|
||||
|
||||
// IMPORTANT ASSUMPTIONS:
|
||||
// - all even sectors consistently increase/decrease momentum for increasing tableau row length
|
||||
// - all odd sectors consistently decrease/increase momentum for increasing tableau row length
|
||||
|
||||
// FOR FIXED MOMENTUM:
|
||||
// all tableau levels `above' the lowest occupied one are descended as for fixed_iK == false,
|
||||
// and the lowest sector's highest tableau level's row length is modified (increased or decreased by one
|
||||
// unit if possible) such that the iK of Tableau_desc == iK of Tableau_ref.
|
||||
// The logic behind this is that for a state with nexc excitations, we let run nexc - 1 of the
|
||||
// excitations, and the lowest one is fixed in place by the momentum constraint, if possible.
|
||||
|
||||
Vect<Young_Tableau> Tableau_ref = (*this).Tableau;
|
||||
Vect<Young_Tableau> Tableau_desc = Tableau_ref;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,89 @@
|
|||
/****************************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c) 2006.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
Combinatorics.cc
|
||||
|
||||
Defines all class related to combinatorics.
|
||||
|
||||
LAST MODIFIED: 04/09/06
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
Choose_Table::Choose_Table ()
|
||||
: Npower(0ULL), Npowerp1(1ULL), table(new unsigned long long int[1])
|
||||
{
|
||||
table[0] = 1ULL;
|
||||
}
|
||||
|
||||
Choose_Table::Choose_Table (int Npower_ref)
|
||||
: Npower(Npower_ref), Npowerp1(Npower_ref + 1ULL)
|
||||
{
|
||||
dim = Npowerp1 * Npowerp1;
|
||||
|
||||
// We can only go up to ULL_MAX:
|
||||
if (log(DP(ULONG_LONG_MAX)) < DP(Npowerp1) * log(2.0))
|
||||
JSCerror("Choose_Table: too large to contruct.");
|
||||
|
||||
table = new unsigned long long int[dim];
|
||||
|
||||
(*this).Fill_table();
|
||||
}
|
||||
|
||||
void Choose_Table::Fill_table()
|
||||
{
|
||||
table[0] = 1ULL;
|
||||
int n,m;
|
||||
for (n = 0; n <= Npower; ++n) {
|
||||
table[Npowerp1 * n] = 1ULL;
|
||||
for (m = 1; m < n; ++m) {
|
||||
table[Npowerp1 * n + m] = table[Npowerp1 * (n-1) + m - 1] + table[Npowerp1 * (n-1) + m];
|
||||
}
|
||||
table[Npowerp1 * n + n] = 1ULL;
|
||||
for (m = n+1; m <= Npower; ++m)
|
||||
table[Npowerp1 * n + m] = 0ULL;
|
||||
}
|
||||
}
|
||||
|
||||
int Choose_Table::power()
|
||||
{
|
||||
return(Npower);
|
||||
}
|
||||
|
||||
unsigned long long int Choose_Table::choose(int N, int M)
|
||||
{
|
||||
if (N < 0 || N > Npower) JSCerror("N out of bounds in choose(N,M).");
|
||||
if (M < 0 || M > Npower) JSCerror("M out of bounds in choose(N,M).");
|
||||
|
||||
return(table[Npowerp1 * N + M]);
|
||||
}
|
||||
|
||||
std::ostream& operator<< (std::ostream& s, Choose_Table& Ref_table)
|
||||
{
|
||||
s << endl;
|
||||
for (int n = 0; n <= Ref_table.power(); ++n) {
|
||||
for (int m = 0; m <= Ref_table.power(); ++m)
|
||||
s << Ref_table.choose(n, m) << " ";
|
||||
s << endl;
|
||||
}
|
||||
s << endl;
|
||||
return(s);
|
||||
}
|
||||
|
||||
Choose_Table::~Choose_Table()
|
||||
{
|
||||
delete[] table;
|
||||
}
|
||||
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,43 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: 2CBG_ThLim.cc
|
||||
|
||||
Purpose: solves the TBA equations for the 2-component Bose gas
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 7) JSCerror("Wrong number of arguments to 2CBG_ThLim executable. Use c(best to set to 1), mu, Omega, kBT, TT(minutes), bool Save_data (0 == false).");
|
||||
|
||||
DP c_int = atof(argv[1]);
|
||||
DP mu = atof(argv[2]);
|
||||
DP Omega = atof(argv[3]);
|
||||
DP kBT = atof(argv[4]);
|
||||
int Max_Secs = 60 * atoi(argv[5]);
|
||||
bool Save_data = bool(atoi(argv[6]));
|
||||
|
||||
if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
|
||||
if (Omega <= 0.0) JSCerror("Give a strictly positive Omega, otherwise the algorithm cannot converge.");
|
||||
if (kBT <= 0.0) JSCerror("Negative T ? You must be a string theorist.");
|
||||
if (Max_Secs < 10) JSCerror("Give more time.");
|
||||
|
||||
//cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
|
||||
|
||||
Solve_2CBG_TBAE_via_refinements (c_int, mu, Omega, kBT, Max_Secs, Save_data);
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Analyze_RAW_File.cc
|
||||
|
||||
Purpose: give some statistics for the matrix element distribution in a raw file.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 4) {
|
||||
cout << "Argument needed: rawfile, iKmin, iKmax." << endl;
|
||||
JSCerror("");
|
||||
}
|
||||
|
||||
const char* rawfilename = argv[1];
|
||||
int iKmin = atoi(argv[2]);
|
||||
int iKmax = atoi(argv[3]);
|
||||
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(rawfilename);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << rawfilename << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
DP sumFFsq = 0.0;
|
||||
DP sumFF4 = 0.0;
|
||||
DP sumFFsqlnFFsq = 0.0;
|
||||
|
||||
Vect<int> nFFatK (0, iKmax - iKmin + 1);
|
||||
Vect<DP> sumFFsqatK (0.0, iKmax - iKmin + 1);
|
||||
Vect<DP> sumFF4atK (0.0, iKmax - iKmin + 1);
|
||||
Vect<DP> sumFFsqlnFFsqatK (0.0, iKmax - iKmin + 1);
|
||||
|
||||
int nread = 0;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
|
||||
nread++;
|
||||
sumFFsq += FF*FF;
|
||||
sumFF4 += FF*FF*FF*FF;
|
||||
sumFFsqlnFFsq += FF*FF * log(FF*FF);
|
||||
|
||||
if (iK >= iKmin && iK <= iKmax) {
|
||||
nFFatK[iK-iKmin] += 1;
|
||||
sumFFsqatK[iK - iKmin] += FF*FF;
|
||||
sumFF4atK[iK - iKmin] += FF*FF*FF*FF;
|
||||
sumFFsqlnFFsqatK[iK - iKmin] += FF*FF * log(FF*FF);
|
||||
}
|
||||
}
|
||||
|
||||
RAW_infile.close();
|
||||
|
||||
cout << "Inverse participation ratio: \t" << sumFF4/(sumFFsq*sumFFsq) << endl;
|
||||
// Entropy is -sum (FFsq/sumFFsq) * ln(FFsq/sumFFsq) = sum (FFsq lnFFsq - FFsq ln sumFFsq)/sumFFsq
|
||||
cout << "Entropy: \t" << -(sumFFsqlnFFsq - sumFFsq * log(sumFFsq))/sumFFsq << endl;
|
||||
|
||||
cout << "iK\tnFFatK\tIPRatiK\tentropyatiK:" << endl;
|
||||
for (int iK = iKmin; iK <= iKmax; ++iK) cout << iK << "\t" << nFFatK[iK-iKmin] << "\t" << sumFF4atK[iK-iKmin]/(sumFFsqatK[iK - iKmin] * sumFFsqatK[iK - iKmin]) << "\t" << -(sumFFsqlnFFsqatK[iK-iKmin] - sumFFsqatK[iK-iKmin] * log(sumFFsqatK[iK-iKmin]))/sumFFsqatK[iK-iKmin]<< endl;
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Check_RAW_File.cc
|
||||
|
||||
Purpose: from a .raw_srt file, check that nonzero momentum states
|
||||
appear (only) twice, and zero momentum ones (only) once.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 7) { // print out some instructions
|
||||
cout << "Usage of Check_RAW_File executable: provide the following arguments:" << endl;
|
||||
cout << "(sorted!) raw file name, iKmin, iKmax, sympoint, FFmin, check_option." << endl;
|
||||
cout << "Check option: 0 == check for missing states, 1 == check for multiply-appearing states." << endl;
|
||||
}
|
||||
|
||||
char* rawfilename = argv[1];
|
||||
int iKmin = atoi(argv[2]);
|
||||
int iKmax = atoi(argv[3]);
|
||||
int sympoint = atoi(argv[4]);
|
||||
DP FFmin = atof(argv[5]);
|
||||
int check_option = atoi(argv[6]);
|
||||
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(rawfilename);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << rawfilename << endl;
|
||||
JSCerror("Could not open sorted RAW_infile... ");
|
||||
}
|
||||
|
||||
DP omega_next, omega, omega_prev;
|
||||
int iK_next, iK, iK_prev;
|
||||
DP FF_next, FF, FF_prev;
|
||||
//int conv_next, conv, conv_prev;
|
||||
DP dev_next, dev, dev_prev;
|
||||
string label_next, label, label_prev;
|
||||
|
||||
if (check_option > 1) {
|
||||
FF = 0.0;
|
||||
FF_prev = 0.0;
|
||||
FF_next = 0.0;
|
||||
FFmin = -1.0;
|
||||
}
|
||||
|
||||
//RAW_infile >> omega >> iK >> FF >> conv >> label;
|
||||
RAW_infile >> omega >> iK;
|
||||
if (check_option <= 1) RAW_infile >> FF;
|
||||
RAW_infile >> dev;
|
||||
RAW_infile >> label;
|
||||
//RAW_infile >> omega_next >> iK_next >> FF_next >> conv_next >> label_next;
|
||||
RAW_infile >> omega_next >> iK_next;
|
||||
if (check_option <= 1) RAW_infile >> FF_next;
|
||||
RAW_infile >> dev_next;
|
||||
RAW_infile >> label_next;
|
||||
|
||||
int line = 1;
|
||||
|
||||
char a;
|
||||
|
||||
|
||||
while (fabs(FF) > FFmin && RAW_infile.peek() != EOF) {
|
||||
|
||||
//omega_prev = omega; iK_prev = iK; FF_prev = FF; conv_prev = conv; label_prev = label;
|
||||
omega_prev = omega; iK_prev = iK; FF_prev = FF; dev_prev = dev; label_prev = label;
|
||||
//omega = omega_next; iK = iK_next; FF = FF_next; conv = conv_next; label = label_next;
|
||||
omega = omega_next; iK = iK_next; FF = FF_next; dev = dev_next; label = label_next;
|
||||
//RAW_infile >> omega_next >> iK_next >> FF_next >> conv_next >> label_next;
|
||||
RAW_infile >> omega_next >> iK_next;
|
||||
if (check_option <= 1) RAW_infile >> FF_next; // for non-Z checks
|
||||
RAW_infile >> dev_next;
|
||||
RAW_infile >> label_next;
|
||||
//cout << "checking line " << line << endl;
|
||||
//cout << omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << label_prev << endl
|
||||
// << omega << "\t" << iK << "\t" << FF << "\t" << label << endl
|
||||
// << omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << label_next << endl;
|
||||
line++;
|
||||
|
||||
if (label.compare(label_next) == 0)
|
||||
cout << "Identical labels around line " << line << ": " << endl
|
||||
<< omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl;
|
||||
|
||||
if (check_option == 0 && iK != 0 && iK != sympoint && iK >= iKmin && iK <= iKmax
|
||||
&& fabs((FF - FF_prev)/(FF + FF_prev)) > 1.0e-6 && fabs((FF - FF_next)/(FF + FF_next)) > 1.0e-6) {
|
||||
|
||||
cout << "State missing around line " << line << ": " << endl
|
||||
//<< omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << conv_prev << "\t" << label_prev << endl
|
||||
<< omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << dev_prev << "\t" << label_prev << endl
|
||||
//<< omega << "\t" << iK << "\t" << FF << "\t" << conv << "\t" << label << endl
|
||||
<< omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl
|
||||
//<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << conv_next << "\t" << label_next << endl;
|
||||
<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << dev_next << "\t" << label_next << endl;
|
||||
|
||||
cin >> a;
|
||||
//break;
|
||||
}
|
||||
|
||||
if (check_option == 1 && iK_prev == iK && iK == iK_next && fabs((omega - omega_prev)/(omega + omega_prev)) < 1.0e-8 && fabs((omega - omega_next)/(omega + omega_next)) < 1.0e-8 && fabs((FF - FF_prev)/(FF + FF_prev)) < 1.0e-8 && fabs((FF - FF_next)/(FF + FF_next)) < 1.0e-8) {
|
||||
|
||||
cout << "Triple state around line " << line << ": " << endl
|
||||
//<< omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << conv_prev << "\t" << label_prev << endl
|
||||
<< omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << dev_prev << "\t" << label_prev << endl
|
||||
//<< omega << "\t" << iK << "\t" << FF << "\t" << conv << "\t" << label << endl
|
||||
<< omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl
|
||||
//<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << conv_next << "\t" << label_next << endl;
|
||||
<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << dev_next << "\t" << label_next << endl;
|
||||
cin >> a;
|
||||
}
|
||||
|
||||
if (check_option == 2 && iK != 0 && iK != sympoint && iK >= iKmin && iK <= iKmax
|
||||
&& fabs((omega - omega_prev)/(omega + omega_prev)) > 1.0e-6 && fabs((omega - omega_next)/(omega + omega_next)) > 1.0e-6) {
|
||||
|
||||
cout << "State missing around line " << line << ": " << endl
|
||||
<< omega_prev << "\t" << iK_prev << "\t" << dev_prev << "\t" << label_prev << endl
|
||||
<< omega << "\t" << iK << "\t" << dev << "\t" << label << endl
|
||||
<< omega_next << "\t" << iK_next << "\t" << dev_next << "\t" << label_next << endl;
|
||||
|
||||
cin >> a;
|
||||
//break;
|
||||
}
|
||||
|
||||
if (check_option == 3 && iK_prev == iK && iK == iK_next && fabs((omega - omega_prev)/(omega + omega_prev)) < 1.0e-8 && fabs((omega - omega_next)/(omega + omega_next)) < 1.0e-8) {
|
||||
|
||||
cout << "Triple state around line " << line << ": " << endl
|
||||
<< omega_prev << "\t" << iK_prev << "\t" << dev_prev << "\t" << label_prev << endl
|
||||
<< omega << "\t" << iK << "\t" << dev << "\t" << label << endl
|
||||
<< omega_next << "\t" << iK_next << "\t" << dev_next << "\t" << label_next << endl;
|
||||
cin >> a;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF.cc
|
||||
|
||||
Purpose: main function for ABACUS++ for Heisenberg spin-1/2 chain
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 8) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
//cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Heis_DSF z 1.0 100 40 0 100 600 1.0 0" << endl << endl;
|
||||
}
|
||||
|
||||
else if (argc == 8) { // !fixed_iK
|
||||
int ctr = 1;
|
||||
char whichDSF = *argv[ctr++];
|
||||
DP Delta = atof(argv[ctr++]);
|
||||
int N = atoi(argv[ctr++]);
|
||||
int M = atoi(argv[ctr++]);
|
||||
//int iKmin = atoi(argv[5]);
|
||||
//int iKmax = atoi(argv[6]);
|
||||
int Max_Secs = atoi(argv[ctr++]);
|
||||
DP target_sumrule = atof(argv[ctr++]);
|
||||
bool refine = (atoi(argv[ctr++]) == 1);
|
||||
|
||||
// We systematically scan over all momentum integers (to avoid problems with Brillouin folding
|
||||
int iKmin = -1000*N;
|
||||
int iKmax = 1000*N;
|
||||
//Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine, 0, 1);
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// The argument given is the name of the standard args_Heis_DSF arguments file
|
||||
|
||||
/*
|
||||
if (argc == 2) { // Used an input file to provide the arguments
|
||||
|
||||
if (strcmp(argv[1],"help") == 0) { // Output some instructions
|
||||
cout << "Usage of Heis_DSF executable: " << endl;
|
||||
cout << endl << "Provide arguments by either using one of the three following options:" << endl << endl;
|
||||
cout << "1) via an argument file (see the template `args_Heis_DSF' in directory src/EXECS/), for example" << endl << endl;
|
||||
cout << "Heis_DSF args_Heis_DSF" << endl << endl;
|
||||
cout << "2) with arguments (for general momenta scan) whichDSF Delta N M iKmin iKmax Max_Secs refine, for example" << endl << endl;
|
||||
cout << "Heis_DSF z 0.9 100 40 0 50 600 0" << endl << endl;
|
||||
cout << "3) with arguments (for general momenta scan) whichDSF Delta N M iKneeded Max_Secs refine, for example" << endl << endl;
|
||||
cout << "Heis_DSF z 0.9 100 40 20 600 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // read argument file
|
||||
|
||||
ifstream argsfile;
|
||||
argsfile.open(argv[1]);
|
||||
if (argsfile.fail()) {
|
||||
cout << argv[1] << endl;
|
||||
JSCerror("Could not open arguments file.");
|
||||
}
|
||||
|
||||
char junk[256];
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
char whichDSF; argsfile >> whichDSF;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
DP Delta; argsfile >> Delta;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
int N; argsfile >> N;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
int M; argsfile >> M;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
//bool fixed_iK; argsfile >> fixed_iK;
|
||||
//while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
//int iKneeded; argsfile >> iKneeded;
|
||||
int iKmin, iKmax; argsfile >> iKmin >> iKmax;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
int Max_Secs; argsfile >> Max_Secs;
|
||||
while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
|
||||
bool refine; argsfile >> refine;
|
||||
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, refine);
|
||||
}
|
||||
} // if (argc == 2)
|
||||
|
||||
else if (argc == 8) { // fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKneeded = atoi(argv[5]);
|
||||
int Max_Secs = atoi(argv[6]);
|
||||
bool refine = (atoi(argv[7]) == 1);
|
||||
|
||||
//Scan_Heis (whichDSF, Delta, N, M, iKneeded, Max_Secs, refine);
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKneeded, iKneeded, Max_Secs, refine);
|
||||
}
|
||||
|
||||
else if (argc == 9) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
int Max_Secs = atoi(argv[7]);
|
||||
bool refine = (atoi(argv[8]) == 1);
|
||||
|
||||
//Scan_Heis (whichDSF, Delta, N, M, iKneeded, Max_Secs, refine);
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, refine);
|
||||
}
|
||||
|
||||
else JSCerror("Wrong number of arguments to Heis_DSF executable.");
|
||||
*/
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF_GeneralState.cc
|
||||
|
||||
Purpose: main function for ABACUS++ for Heisenberg spin-1/2 chain
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
//cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
}
|
||||
|
||||
else if (argc == 9) { // !fixed_iK
|
||||
int ctr = 1;
|
||||
char whichDSF = *argv[ctr++];
|
||||
DP Delta = atof(argv[ctr++]);
|
||||
int N = atoi(argv[ctr++]);
|
||||
int M = atoi(argv[ctr++]);
|
||||
char* Ix2filenameprefix = argv[ctr++];
|
||||
//int iKmin = atoi(argv[5]);
|
||||
//int iKmax = atoi(argv[6]);
|
||||
int Max_Secs = atoi(argv[ctr++]);
|
||||
DP target_sumrule = atof(argv[ctr++]);
|
||||
bool refine = (atoi(argv[ctr++]) == 1);
|
||||
|
||||
// We systematically scan over all momentum integers (to avoid problems with Brillouin folding
|
||||
int iKmin = -1000*N;
|
||||
int iKmax = 1000*N;
|
||||
|
||||
// Read the Ix2 from the file:
|
||||
// Format is:
|
||||
// base_level, Nrap[base_level], \endl Ix2[base_level], repeat for all occupied base_levels...
|
||||
ifstream Ix2_input_file;
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
filenamestrstream << ".Ix2";
|
||||
string filenamestr = filenamestrstream.str();
|
||||
const char* filename_Cstr = filenamestr.c_str();
|
||||
Ix2_input_file.open(filename_Cstr);
|
||||
if (Ix2_input_file.fail()) {
|
||||
cout << filename_Cstr << endl;
|
||||
JSCerror("Could not open Ix2 input file in Heis_DSF_GeneralState");
|
||||
}
|
||||
|
||||
Heis_Chain chain(1.0, Delta, 0.0, N);
|
||||
|
||||
Vect<int> Nrap_read (0, chain.Nstrings);
|
||||
int level = 0;
|
||||
Vect<Vect<int> > Ix2_read (chain.Nstrings);
|
||||
do {
|
||||
Ix2_input_file >> level;
|
||||
Ix2_input_file >> Nrap_read[level];
|
||||
Ix2_read[level] = Vect<int> (Nrap_read[level]);
|
||||
for (int alpha = 0; alpha < Nrap_read[level]; ++alpha) Ix2_input_file >> Ix2_read[level][alpha];
|
||||
//cout << "Read level = " << level << "\tNrap_read[level] = " << Nrap_read[level] << endl;
|
||||
//cout << "\tIx2_read[level] = " << Ix2_read[level] << endl;
|
||||
} while (Ix2_input_file.peek() != EOF);
|
||||
|
||||
// Construct the Averaging State:
|
||||
Heis_Base base (chain, Nrap_read);
|
||||
|
||||
int paralevel = 0;
|
||||
Vect<int> rank; // dummy
|
||||
Vect<int> nr_processors; // dummy
|
||||
|
||||
if (Delta > 0.0 && Delta < 1.0) {
|
||||
XXZ_Bethe_State AveragingState (chain, base);
|
||||
for (int il = 0; il < chain.Nstrings; ++il) {
|
||||
if (Nrap_read[il] > 0) for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
|
||||
}
|
||||
AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
|
||||
AveragingState.Compute_All(true);
|
||||
|
||||
//cout << "AveragingState read from file: " << AveragingState << endl;
|
||||
// Perform the scan:
|
||||
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
}
|
||||
else if (Delta == 1.0) {
|
||||
XXX_Bethe_State AveragingState (chain, base);
|
||||
for (int il = 0; il < chain.Nstrings; ++il) {
|
||||
for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
|
||||
}
|
||||
AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
|
||||
AveragingState.Compute_All(true);
|
||||
|
||||
// Perform the scan:
|
||||
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
}
|
||||
else if (Delta > 1.0) {
|
||||
XXZ_gpd_Bethe_State AveragingState (chain, base);
|
||||
for (int il = 0; il < chain.Nstrings; ++il) {
|
||||
for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
|
||||
}
|
||||
AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
|
||||
AveragingState.Compute_All(true);
|
||||
|
||||
// Perform the scan:
|
||||
Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF_par.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP Delta;
|
||||
int N, M, iKneeded, iKmin, iKmax, Max_Secs;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine;
|
||||
|
||||
if (argc != 8) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF_par executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "mpiexec -np 8 Heis_DSF_par z 1.0 100 40 0 100 600" << endl << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // (argc == 8) correct nr of arguments
|
||||
whichDSF = *argv[1];
|
||||
Delta = atof(argv[2]);
|
||||
N = atoi(argv[3]);
|
||||
M = atoi(argv[4]);
|
||||
iKmin = atoi(argv[5]);
|
||||
iKmax = atoi(argv[6]);
|
||||
Max_Secs = atoi(argv[7]);
|
||||
}
|
||||
|
||||
DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= supercycle_time + 300) JSCerror("Please allow more time in Heis_DSF_par.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
// IMPORTANT PRECONDITION: no flags are being raised in General_Scan in parallel mode, so
|
||||
// the preinitializing serial run must be extensive enough to have flagged all base/type s necessary.
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
while (tnow - tstart < Max_Secs - supercycle_time - 300) { // space for one more supercycle, + 5 minutes safety
|
||||
|
||||
//cout << "rank " << rank << " ready to prepare." << endl;
|
||||
|
||||
if (rank == 0)
|
||||
// Split up thread list into chunks, one per processor
|
||||
Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors);
|
||||
|
||||
//cout << "rank " << rank << " done preparing, ready to scan." << endl;
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax,
|
||||
supercycle_time, target_sumrule, refine, rank, nr_processors);
|
||||
|
||||
//cout << "rank " << rank << " finished scanning, reached wrapup stage." << endl;
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
if (rank == 0)
|
||||
Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors);
|
||||
|
||||
//cout << "rank " << rank << " passed wrapup stage." << endl;
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP Delta;
|
||||
int N, M, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF_par_Prepare executable: " << endl;
|
||||
cout << endl << "This function prepares for ABACUS++G in parallel mode, starting from a preexisting serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
Delta = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
M = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 9 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in Heis_DSF_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
// Split up thread list into chunks, one per processor
|
||||
Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF_par_Run.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP Delta;
|
||||
int N, M, iKmin, iKmax, Max_Secs, supercycle_time, paralevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF_par_Run executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the Heis_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "mpiexec -np 8 Heis_DSF_par_Run z 1 128 64 0 128 [**UPDATE]" << endl << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//else { // (argc == 9) correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
Delta = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
M = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in Heis_DSF_par_Run.");
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
Max_Secs = atoi(argv[n++]);
|
||||
supercycle_time = atoi(argv[n++]);
|
||||
//}
|
||||
|
||||
//DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in Heis_DSF_par_Run.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank_here = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors_here = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
Vect<int> rank (paralevel);
|
||||
Vect<int> nr_processors (paralevel);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank[i] = rank_lower_paralevels[i];
|
||||
nr_processors[i] = nr_processors_lower_paralevels[i];
|
||||
}
|
||||
rank[paralevel-1] = rank_here;
|
||||
nr_processors[paralevel-1] = nr_processors_here;
|
||||
|
||||
if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax,
|
||||
supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Heis_DSF_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare or Wrapup
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP Delta;
|
||||
int N, M, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Heis_DSF_par_Wrapup executable: " << endl;
|
||||
cout << endl << "This function wraps up an ABACUS++G parallel mode run." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
Delta = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
M = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 9 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in Heis_DSF_par_Wrapup.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
// Split up thread list into chunks, one per processor
|
||||
Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Catalogue_Fixed_c_k_Nscaling.cc
|
||||
|
||||
Purpose: Produces sets of data files for correlations, increasing system size at fixed c and momentum.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 7) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Catalogue_Fixed_c_k_Nscaling executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
//cout << "int Nc \t\t number of steps in interaction value" << endl;
|
||||
//cout << "int Nstep \t\t\t Steps to be taken in number of particles: use positive integer values only. Filling will be set to 1 (L == N)" << endl;
|
||||
//cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over (in units of N == Nstep): recommended values: 0 and 2*N" << endl;
|
||||
cout << "int kfact \t\t momentum factor: momemntum will be set to kfact * kF/4" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time" << endl;
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int ia = 1;
|
||||
char whichDSF = *argv[ia++];
|
||||
DP c_int = atof(argv[ia++]);
|
||||
int kfact = atoi(argv[ia++]);
|
||||
DP kBT = atof(argv[ia++]);
|
||||
DP target_sumrule = atof(argv[ia++]);
|
||||
int Max_Secs = atoi(argv[ia++]);
|
||||
|
||||
|
||||
//clock_t StartTime = clock();
|
||||
double StartTime = omp_get_wtime();
|
||||
|
||||
//clock_t ActualTime = StartTime;
|
||||
double ActualTime = omp_get_wtime();
|
||||
|
||||
int Secs_left = Max_Secs;
|
||||
|
||||
int iN = 0;
|
||||
|
||||
int nN = 12;
|
||||
Vect<int> Nv(nN);
|
||||
Nv[0] = 160; Nv[1] = 192; Nv[2] = 224; Nv[3] = 256;
|
||||
Nv[4] = 320; Nv[5] = 384; Nv[6] = 448; Nv[7] = 512;
|
||||
Nv[8] = 640; Nv[9] = 768; Nv[10] = 896; Nv[11] = 1024;
|
||||
|
||||
for (int iN = 0; iN < nN; ++iN) {
|
||||
|
||||
int N = Nv[iN];
|
||||
DP L = N;
|
||||
int iKmin = (kfact * N)/8;
|
||||
int iKmax = iKmin;
|
||||
DP srsat = 0.0;
|
||||
bool refine = false;
|
||||
|
||||
stringstream SRC_stringstream; string SRC_string;
|
||||
Data_File_Name (SRC_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
SRC_stringstream << ".src";
|
||||
SRC_string = SRC_stringstream.str(); const char* SRC_Cstr = SRC_string.c_str();
|
||||
|
||||
fstream srcfile;
|
||||
srcfile.open(SRC_Cstr, fstream::in);
|
||||
if (srcfile.fail()) {
|
||||
srsat = 0.0;
|
||||
refine = false;
|
||||
}
|
||||
else {
|
||||
srcfile >> srsat;
|
||||
refine = true;
|
||||
}
|
||||
srcfile.close();
|
||||
|
||||
ActualTime = omp_get_wtime();
|
||||
Secs_left = int(Max_Secs - (ActualTime - StartTime));
|
||||
|
||||
if (srsat < target_sumrule && Secs_left > Max_Secs/2)
|
||||
// Improve the icmin calculation by one chunk:
|
||||
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Secs_left, target_sumrule, refine);
|
||||
|
||||
ActualTime = omp_get_wtime();
|
||||
|
||||
//Secs_left = int(60*Max_minutes - double(ActualTime - StartTime)/CLOCKS_PER_SEC);
|
||||
Secs_left = int(Max_Secs - (ActualTime - StartTime));
|
||||
cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl;
|
||||
|
||||
if (Secs_left < 60) {
|
||||
cout << "Breaking out after N = " << N << " since time left = " << Secs_left << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
} // while there is time
|
||||
|
||||
} // else if arguments given OK
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF.cc
|
||||
|
||||
Purpose: main function for ABACUS++ for LiebLin gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 11) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF d 1.0 100.0 100 0 200 0.56 600 1.0 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int Max_Secs = atoi(argv[8]);
|
||||
DP target_sumrule = atof(argv[9]);
|
||||
bool refine = (atoi(argv[10]) == 1);
|
||||
|
||||
//cout << "target_sumrule = " << target_sumrule << endl;
|
||||
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine, 0, 1);
|
||||
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_GeneralState.cc
|
||||
|
||||
Purpose: function for ABACUS++ for LiebLin gas, on general states
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 11) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF d 1.0 100.0 100 0 200 0.56 600 1.0 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
int n = 1;
|
||||
char whichDSF = *argv[n++];
|
||||
DP c_int = atof(argv[n++]);
|
||||
DP L = atof(argv[n++]);
|
||||
int N = atoi(argv[n++]);
|
||||
char* Ix2filenameprefix = argv[n++];
|
||||
int iKmin = atoi(argv[n++]);
|
||||
int iKmax = atoi(argv[n++]);
|
||||
//DP kBT = atof(argv[n++]);
|
||||
int Max_Secs = atoi(argv[n++]);
|
||||
DP target_sumrule = atof(argv[n++]);
|
||||
bool refine = (atoi(argv[n++]) == 1);
|
||||
|
||||
// Read the Ix2 from the file:
|
||||
Vect<int> Ix2_input(N);
|
||||
ifstream Ix2_input_file;
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
filenamestrstream << ".Ix2";
|
||||
string filenamestr = filenamestrstream.str();
|
||||
const char* filename_Cstr = filenamestr.c_str();
|
||||
Ix2_input_file.open(filename_Cstr);
|
||||
if (Ix2_input_file.fail()) {
|
||||
cout << filename_Cstr << endl;
|
||||
JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
Ix2_input_file >> Ix2_input[i];
|
||||
//cout << i << "\t" << Ix2_input[i] << endl;
|
||||
}
|
||||
|
||||
// Now define the AveragingState
|
||||
LiebLin_Bethe_State AveragingState(c_int, L, N);
|
||||
AveragingState.Ix2 = Ix2_input;
|
||||
AveragingState.Compute_All(true);
|
||||
|
||||
//cout << "Averaging state: " << AveragingState << endl;
|
||||
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine, 0, 1);
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine);
|
||||
|
||||
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
|
||||
// int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors)
|
||||
// Simplified function call of the above:
|
||||
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
|
||||
// int Max_Secs, DP target_sumrule, bool refine)
|
||||
Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_GeneralState_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
char* Ix2filenameprefix;
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par_Prepare executable: " << endl;
|
||||
cout << endl << "This function prepares an ABACUS++ parallel mode run, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Ix2filenameprefix = argv[n++];
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
//kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_GeneralState_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
|
||||
// Read the Ix2 from the file:
|
||||
Vect<int> Ix2_input(N);
|
||||
ifstream Ix2_input_file;
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
/*
|
||||
filenamestrstream << ".Ix2";
|
||||
string filenamestr = filenamestrstream.str();
|
||||
const char* filename_Cstr = filenamestr.c_str();
|
||||
Ix2_input_file.open(filename_Cstr);
|
||||
if (Ix2_input_file.fail()) {
|
||||
cout << filename_Cstr << endl;
|
||||
JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
Ix2_input_file >> Ix2_input[i];
|
||||
//cout << i << "\t" << Ix2_input[i] << endl;
|
||||
}
|
||||
|
||||
// Define the AveragingState
|
||||
LiebLin_Bethe_State AveragingState(c_int, L, N);
|
||||
AveragingState.Ix2 = Ix2_input;
|
||||
//AveragingState.Compute_All(true);
|
||||
*/
|
||||
|
||||
// Split up thread list into chunks, one per processor
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_GeneralState_par_Run.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, Max_Secs, paralevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
char* Ix2filenameprefix;
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
//cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Ix2filenameprefix = argv[n++];
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
//kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
Max_Secs = atoi(argv[n++]);
|
||||
// supercycle_time = atoi(argv[n++]);
|
||||
//}
|
||||
|
||||
//DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= 120) JSCerror("Please allow more time in LiebLin_DSF_par_Run.");
|
||||
|
||||
int Max_Secs_used = Max_Secs - 120;
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank_here = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors_here = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
// Read the Ix2 from the file:
|
||||
Vect<int> Ix2_input(N);
|
||||
ifstream Ix2_input_file;
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
filenamestrstream << ".Ix2";
|
||||
string filenamestr = filenamestrstream.str();
|
||||
const char* filename_Cstr = filenamestr.c_str();
|
||||
Ix2_input_file.open(filename_Cstr);
|
||||
if (Ix2_input_file.fail()) {
|
||||
cout << filename_Cstr << endl;
|
||||
JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
Ix2_input_file >> Ix2_input[i];
|
||||
//cout << i << "\t" << Ix2_input[i] << endl;
|
||||
}
|
||||
|
||||
// Now define the AveragingState
|
||||
LiebLin_Bethe_State AveragingState(c_int, L, N);
|
||||
AveragingState.Ix2 = Ix2_input;
|
||||
AveragingState.Compute_All(true);
|
||||
|
||||
|
||||
Vect<int> rank (paralevel);
|
||||
Vect<int> nr_processors (paralevel);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank[i] = rank_lower_paralevels[i];
|
||||
nr_processors[i] = nr_processors_lower_paralevels[i];
|
||||
}
|
||||
rank[paralevel-1] = rank_here;
|
||||
nr_processors[paralevel-1] = nr_processors_here;
|
||||
|
||||
if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
|
||||
//while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
|
||||
if (Max_Secs_used > 0) {
|
||||
|
||||
// Barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
|
||||
// supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
char* Ix2filenameprefix;
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par_Wrapup executable: " << endl;
|
||||
cout << endl << "This function wraps up an ABACUS++ parallel mode run." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Ix2filenameprefix = argv[n++];
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
//kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
// Read the Ix2 from the file:
|
||||
Vect<int> Ix2_input(N);
|
||||
ifstream Ix2_input_file;
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
/*
|
||||
filenamestrstream << ".Ix2";
|
||||
string filenamestr = filenamestrstream.str();
|
||||
const char* filename_Cstr = filenamestr.c_str();
|
||||
Ix2_input_file.open(filename_Cstr);
|
||||
if (Ix2_input_file.fail()) {
|
||||
cout << filename_Cstr << endl;
|
||||
JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
|
||||
}
|
||||
for (int i = 0; i < N; ++i) {
|
||||
Ix2_input_file >> Ix2_input[i];
|
||||
//cout << i << "\t" << Ix2_input[i] << endl;
|
||||
}
|
||||
|
||||
// Define the AveragingState
|
||||
LiebLin_Bethe_State AveragingState(c_int, L, N);
|
||||
AveragingState.Ix2 = Ix2_input;
|
||||
//AveragingState.Compute_All(true);
|
||||
*/
|
||||
|
||||
// Digest files into a unique one for the latest paralevel:
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF.cc
|
||||
|
||||
Purpose: main function for ABACUS++ for LiebLin gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 13) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_MosesState executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
//cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF_MosesState d 1.0 100.0 100 50 -30 20 0 200 600 1.0 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 13), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int Nl = atoi(argv[5]);
|
||||
//int Nr = N - Nl;
|
||||
int DIl = atoi(argv[6]);
|
||||
int DIr = atoi(argv[7]);
|
||||
int iKmin = atoi(argv[8]);
|
||||
int iKmax = atoi(argv[9]);
|
||||
//DP kBT = atof(argv[7]);
|
||||
int Max_Secs = atoi(argv[10]);
|
||||
DP target_sumrule = atof(argv[11]);
|
||||
bool refine = (atoi(argv[12]) == 1);
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
//cout << MosesState << endl;
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
// Compute the correlation:
|
||||
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L;
|
||||
int N, Nl, DIl, DIr, iKmin, iKmax, Max_Secs, supercycle_time;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
DP kBT = 0.0; // dummy
|
||||
|
||||
if (argc != 12) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_MosesState_par executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "mpiexec -np 8 LiebLin_DSF_MosesState_par d 1.0 100.0 100 50 -30 20 -400 400 3600 600" << endl << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // (argc == 11) correct nr of arguments
|
||||
whichDSF = *argv[1];
|
||||
c_int = atof(argv[2]);
|
||||
L = atof(argv[3]);
|
||||
N = atoi(argv[4]);
|
||||
Nl = atoi(argv[5]);
|
||||
DIl = atoi(argv[6]);
|
||||
DIr = atoi(argv[7]);
|
||||
iKmin = atoi(argv[8]);
|
||||
iKmax = atoi(argv[9]);
|
||||
Max_Secs = atoi(argv[10]);
|
||||
supercycle_time = atoi(argv[11]);
|
||||
}
|
||||
|
||||
//DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
|
||||
|
||||
if (rank == 0)
|
||||
// Split up thread list into chunks, one per processor
|
||||
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, supercycle_time, target_sumrule, refine, rank, nr_processors);
|
||||
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time, target_sumrule, refine, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
|
||||
if (rank == 0)
|
||||
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L;
|
||||
int N, Nl, DIl, DIr, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
DP kBT = 0.0; // dummy
|
||||
|
||||
if (argc < 12) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Prepare executable: " << endl;
|
||||
cout << endl << "This function prepares an ABACUS++ parallel mode run, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Nl = atoi(argv[n++]);
|
||||
DIl = atoi(argv[n++]);
|
||||
DIr = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 12 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_MosesState_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
|
||||
// Split up thread list into chunks, one per processor
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L;
|
||||
int N, Nl, DIl, DIr, iKmin, iKmax, Max_Secs, supercycle_time, paralevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
DP kBT = 0.0; // dummy
|
||||
|
||||
if (argc < 13) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Run executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Nl = atoi(argv[n++]);
|
||||
DIl = atoi(argv[n++]);
|
||||
DIr = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 13 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
Max_Secs = atoi(argv[n++]);
|
||||
supercycle_time = atoi(argv[n++]);
|
||||
//}
|
||||
|
||||
//DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par_Run.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank_here = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors_here = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
//cout << "rank " << rank_here << " out of " << nr_processors_here << " ready to go." << endl;
|
||||
|
||||
Vect<int> rank (paralevel);
|
||||
Vect<int> nr_processors (paralevel);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank[i] = rank_lower_paralevels[i];
|
||||
nr_processors[i] = nr_processors_lower_paralevels[i];
|
||||
}
|
||||
rank[paralevel-1] = rank_here;
|
||||
nr_processors[paralevel-1] = nr_processors_here;
|
||||
|
||||
if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
//cout << "rank " << rank_here << " out of " << nr_processors_here << " waiting at barrier." << endl;
|
||||
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
|
||||
while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
|
||||
|
||||
//if (rank == 0)
|
||||
// Split up thread list into chunks, one per processor
|
||||
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
|
||||
//if (rank == 0)
|
||||
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_MosesState_par_Wrapup.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L;
|
||||
int N, Nl, DIl, DIr, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
DP kBT = 0.0; // dummy
|
||||
|
||||
if (argc < 12) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_MosesState_par_Wrapup executable: " << endl;
|
||||
cout << endl << "This function wraps up an ABACUS++ parallel mode run." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
Nl = atoi(argv[n++]);
|
||||
DIl = atoi(argv[n++]);
|
||||
DIr = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 12 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_MosesState_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
|
||||
// Digest files into a unique one for the latest paralevel:
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_over_Ensemble.cc
|
||||
|
||||
Purpose: main function for ABACUS++T for LiebLin gas, averaging over an Ensemble.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
//cout << "int nstates \t\t\t Number of states to be considered in the ensemble" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
//cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 0.56 10 600 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
//int nstates_req = atoi(argv[8]);
|
||||
int Max_Secs = atoi(argv[8]);
|
||||
bool refine = (atoi(argv[9]) == 1);
|
||||
|
||||
// Start by constructing (or loading) the state ensemble.
|
||||
|
||||
LiebLin_Diagonal_State_Ensemble ensemble;
|
||||
|
||||
stringstream ensfilestrstream;
|
||||
//ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
|
||||
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
|
||||
string ensfilestr = ensfilestrstream.str();
|
||||
const char* ensfile_Cstr = ensfilestr.c_str();
|
||||
|
||||
if (!refine) { // Construct the state ensemble
|
||||
//ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT, nstates_req);
|
||||
ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT);
|
||||
ensemble.Save(ensfile_Cstr); // Save the ensemble
|
||||
}
|
||||
|
||||
else { // load the ensemble data
|
||||
ensemble.Load(c_int, L, N, ensfile_Cstr);
|
||||
}
|
||||
|
||||
// Now perform the DSF calculation over each state in the ensemble, distributing the time according to the weight
|
||||
|
||||
for (int ns = 0; ns < ensemble.nstates; ++ns) {
|
||||
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
|
||||
//int Max_Secs, DP target_sumrule, bool refine, int rank, int nr_processors)
|
||||
//Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, int(Max_Secs * ensemble.weight[ns]), 1.0e+6, refine, 0, 1);
|
||||
Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, int(Max_Secs * ensemble.weight[ns]), 1.0e+6, refine);
|
||||
}
|
||||
|
||||
// Evaluate the f-sumrule
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
Data_File_Name (FSR_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
FSR_stringstream << "_ns_" << ensemble.nstates << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
|
||||
DP Chem_Pot = 0.0;
|
||||
|
||||
Evaluate_F_Sumrule (whichDSF, c_int, L, N, kBT, ensemble.nstates, Chem_Pot, iKmin, iKmax, FSR_Cstr);
|
||||
|
||||
|
||||
} // correct nr of arguments
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_over_Ensemble_par.cc
|
||||
|
||||
Purpose: main function for ABACUS for LiebLin gas, averaging over an Ensemble, parallel implementation.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
//cout << "int nstates \t\t\t Number of states to be considered in the ensemble" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
//cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 0.56 10 600 0" << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
//int nstates_req = atoi(argv[8]);
|
||||
int Max_Secs = atoi(argv[8]);
|
||||
bool refine = (atoi(argv[9]) == 1);
|
||||
|
||||
if (refine == false) JSCerror("Please run the serial version of LiebLin_DSF_over_Ensemble first.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
|
||||
// Start by constructing (or loading) the state ensemble.
|
||||
|
||||
LiebLin_Diagonal_State_Ensemble ensemble;
|
||||
|
||||
stringstream ensfilestrstream;
|
||||
//ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
|
||||
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
|
||||
string ensfilestr = ensfilestrstream.str();
|
||||
const char* ensfile_Cstr = ensfilestr.c_str();
|
||||
|
||||
if (!refine) { // Construct the state ensemble
|
||||
//ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT, nstates_req);
|
||||
ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT);
|
||||
ensemble.Save(ensfile_Cstr); // Save the ensemble
|
||||
}
|
||||
|
||||
else { // load the ensemble data
|
||||
ensemble.Load(c_int, L, N, ensfile_Cstr);
|
||||
}
|
||||
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now perform the DSF calculation over each state in the ensemble
|
||||
|
||||
/* Original implementation: Scan always called serially. Superseded by version below, using successive parallel scans on each state in the ensemble.
|
||||
int nDSFperproc = ensemble.nstates/nr_processors + 1;
|
||||
//if (ensemble.nstates % nr_processors) JSCerror("Use nr_processors * integer multiple == ensemble.nstates in LiebLin_DSF_over_Ensemble_par.");
|
||||
|
||||
// Processor with rank r does all
|
||||
|
||||
int ns;
|
||||
int Max_Secs_used = Max_Secs/nDSFperproc;
|
||||
|
||||
for (int ir = 0; ir < nDSFperproc; ++ir) {
|
||||
ns = rank + ir * nr_processors;
|
||||
//void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax,
|
||||
//int Max_Secs, DP target_sumrule, bool refine, int rank, int nr_processors)
|
||||
if (ns < ensemble.nstates) {
|
||||
//cout << "Processor rank " << rank << " going for ns = " << ns << " out of " << ensemble.nstates << endl;
|
||||
Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, Max_Secs_used, 1.0e+6, refine, 0, 1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Version 2013 04 24:
|
||||
// Makes use of a parallel scan for each state in the ensemble, in succession.
|
||||
// Code is simple adaptation of LiebLin_DSF_par executable code.
|
||||
|
||||
int Max_Secs_used = Max_Secs/ensemble.nstates;
|
||||
|
||||
DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs_used <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par.");
|
||||
|
||||
// Main loop over ensemble:
|
||||
for (int ns = 0; ns < ensemble.nstates; ++ns) {
|
||||
|
||||
tstart = MPI::Wtime();
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
string defaultScanStatename = ensemble.state[ns].label;
|
||||
|
||||
while (tnow - tstart < Max_Secs_used - supercycle_time) { // space for one more supercycle
|
||||
|
||||
if (rank == 0)
|
||||
// Split up thread list into chunks, one per processor
|
||||
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
|
||||
//supercycle_time, target_sumrule, refine, rank, nr_processors);
|
||||
Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, supercycle_time, 1.0e+6, refine, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
|
||||
if (rank == 0)
|
||||
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
} // for ns
|
||||
|
||||
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
|
||||
// Final wrapup of the data
|
||||
if (rank == 0) {
|
||||
|
||||
// Evaluate the f-sumrule
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
Data_File_Name (FSR_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
FSR_stringstream << "_ns_" << ensemble.nstates << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
|
||||
DP Chem_Pot = 0.0;
|
||||
|
||||
Evaluate_F_Sumrule (whichDSF, c_int, L, N, kBT, ensemble.nstates, Chem_Pot, iKmin, iKmax, FSR_Cstr);
|
||||
}
|
||||
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
} // correct nr of arguments
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, Max_Secs, supercycle_time;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "mpiexec -np 8 LiebLin_DSF_MosesState_par d 1.0 100.0 100 -400 400 0.0 3600 600" << endl << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // (argc == 9) correct nr of arguments
|
||||
whichDSF = *argv[1];
|
||||
c_int = atof(argv[2]);
|
||||
L = atof(argv[3]);
|
||||
N = atoi(argv[4]);
|
||||
iKmin = atoi(argv[5]);
|
||||
iKmax = atoi(argv[6]);
|
||||
kBT = atof(argv[7]);
|
||||
Max_Secs = atoi(argv[8]);
|
||||
supercycle_time = atoi(argv[9]);
|
||||
}
|
||||
|
||||
//DP supercycle_time = 600.0; // allotted time per supercycle
|
||||
|
||||
if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par.");
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
|
||||
|
||||
if (rank == 0)
|
||||
// Split up thread list into chunks, one per processor
|
||||
//Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Barrier synchronization, to make sure other processes wait for process of rank 0
|
||||
// to have finished splitting up the thr file into pieces before starting:
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
|
||||
supercycle_time, target_sumrule, refine, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// Now that everybody is done, digest data into unique files
|
||||
|
||||
if (rank == 0)
|
||||
//Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
} // while (tnow - tstart...
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par_Prepare.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par_Prepare executable: " << endl;
|
||||
cout << endl << "This function prepares an ABACUS++ parallel mode run, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
// Split up thread list into chunks, one per processor
|
||||
Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par_Run.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
#include "mpi.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, Max_Secs, paralevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par_Run executable: " << endl;
|
||||
cout << endl << "This function runs ABACUS++ in parallel mode, starting from a preexisting serial run (obtained using the LiebLin_DSF executable) using the same model parameters." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "mpiexec -np 8 LiebLin_DSF_par_Run d 1.0 100.0 100 0 400 0.0 1 3600" << endl << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Run.");
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
Max_Secs = atoi(argv[n++]);
|
||||
|
||||
if (Max_Secs < 120) JSCerror("Please allow more time in LiebLin_DSF_par_Run.");
|
||||
|
||||
int Max_Secs_used = Max_Secs - 120;
|
||||
|
||||
MPI::Init(argc, argv);
|
||||
|
||||
DP tstart = MPI::Wtime();
|
||||
|
||||
int rank_here = MPI::COMM_WORLD.Get_rank();
|
||||
int nr_processors_here = MPI::COMM_WORLD.Get_size();
|
||||
|
||||
Vect<int> rank (paralevel);
|
||||
Vect<int> nr_processors (paralevel);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank[i] = rank_lower_paralevels[i];
|
||||
nr_processors[i] = nr_processors_lower_paralevels[i];
|
||||
}
|
||||
rank[paralevel-1] = rank_here;
|
||||
nr_processors[paralevel-1] = nr_processors_here;
|
||||
|
||||
if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS parallel !");
|
||||
|
||||
refine = true;
|
||||
|
||||
// ASSUMPTION: preexisting files (raw, thr, ...) exist for the run.
|
||||
|
||||
|
||||
DP tnow = MPI::Wtime();
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
if (Max_Secs_used > 0) { // space for 2 minutes safety
|
||||
|
||||
// Barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
// then everybody gets going on their own chunk !
|
||||
//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded,
|
||||
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
|
||||
Max_Secs_used, target_sumrule, refine, paralevel, rank, nr_processors);
|
||||
|
||||
// Another barrier synchronization
|
||||
MPI_Barrier (MPI::COMM_WORLD);
|
||||
|
||||
tnow = MPI::Wtime();
|
||||
|
||||
}
|
||||
|
||||
MPI::Finalize();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_par_Wrapup.cc
|
||||
|
||||
Purpose: Parallel version of ABACUS++ using MPICH.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
//#include "mpi.h" // not needed for Prepare or Wrapup
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char whichDSF;
|
||||
DP c_int, L, kBT;
|
||||
int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
|
||||
DP target_sumrule = 1.0e+6; // effectively deactivated here
|
||||
bool refine = true; // always true for parallel mode
|
||||
|
||||
if (argc < 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_par_Wrapup executable: " << endl;
|
||||
cout << endl << "This function wraps up an ABACUS++ parallel mode run." << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int paralevel" << endl;
|
||||
cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
|
||||
cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
int n = 1;
|
||||
whichDSF = *argv[n++];
|
||||
c_int = atof(argv[n++]);
|
||||
L = atof(argv[n++]);
|
||||
N = atoi(argv[n++]);
|
||||
iKmin = atoi(argv[n++]);
|
||||
iKmax = atoi(argv[n++]);
|
||||
kBT = atof(argv[n++]);
|
||||
paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
|
||||
if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Wrapup.");
|
||||
|
||||
Vect<int> rank_lower_paralevels(paralevel - 1);
|
||||
Vect<int> nr_processors_lower_paralevels(paralevel - 1);
|
||||
for (int i = 0; i < paralevel - 1; ++i) {
|
||||
rank_lower_paralevels[i] = atoi(argv[n++]);
|
||||
nr_processors_lower_paralevels[i] = atoi(argv[n++]);
|
||||
}
|
||||
nr_processors_at_newlevel = atoi(argv[n++]);
|
||||
|
||||
string defaultScanStatename = "";
|
||||
|
||||
// Digest files into a unique one for the latest paralevel:
|
||||
Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_tester.cc
|
||||
|
||||
Purpose: allows for Ix2 manipulations (user-prompted) for LiebLin gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 6) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF_tester d 1.0 100.0 100 0.56 " << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 6), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
DP kBT = atof(argv[5]);
|
||||
|
||||
//if (whichDSF != 'd') JSCerror("Other options not implemented yet in finite T Scan_LiebLin");
|
||||
|
||||
// Delta is the number of sites involved in the smoothing of the entropy
|
||||
//int Delta = int(sqrt(N))/2;//6;//N/20;
|
||||
|
||||
// Construct the finite-size saddle-point state:
|
||||
//LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT, Delta);
|
||||
LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
|
||||
spstate.Compute_All(true);
|
||||
|
||||
LiebLin_Bethe_State estate = spstate;
|
||||
if (whichDSF == 'o') estate = Remove_Particle_at_Center (spstate);
|
||||
else if (whichDSF == 'g') estate = Add_Particle_at_Center (spstate);
|
||||
if (whichDSF != 'd') estate.Compute_All(true);
|
||||
cout << estate << endl;
|
||||
Vect<int> OriginIx2 = estate.Ix2;
|
||||
|
||||
int Ix2old, Ix2new;
|
||||
int again = 0;
|
||||
string label_req;
|
||||
do {
|
||||
//cout << "Substitute Ix2: which for which ?" << endl;
|
||||
//cin >> Ix2old >> Ix2new;
|
||||
//for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new;
|
||||
//estate.Ix2.QuickSort();
|
||||
cout << "Which label should the exc state be set to?" << endl;
|
||||
cin >> label_req;
|
||||
estate.Set_to_Label(label_req, OriginIx2);
|
||||
estate.Compute_All(false);
|
||||
cout << spstate << endl;
|
||||
cout << estate;
|
||||
if (whichDSF == 'd')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Density_ME(spstate, estate))) << endl;
|
||||
else if (whichDSF == 'o')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(estate, spstate))) << endl;
|
||||
else if (whichDSF == 'g')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(spstate, estate))) << endl;
|
||||
|
||||
//cout << "Another try ? (1 == yes, 0 == no)" << endl;
|
||||
again = 1;
|
||||
cin >> again;
|
||||
} while (again != 0);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_tester.cc
|
||||
|
||||
Purpose: allows for Ix2 manipulations (user-prompted) for LiebLin gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 6) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "LiebLin_DSF_tester d 1.0 100.0 100 0.56 " << endl << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 6), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
DP kBT = atof(argv[5]);
|
||||
|
||||
//if (whichDSF != 'd') JSCerror("Other options not implemented yet in finite T Scan_LiebLin");
|
||||
|
||||
// Delta is the number of sites involved in the smoothing of the entropy
|
||||
//int Delta = int(sqrt(N))/2;//6;//N/20;
|
||||
|
||||
// Construct the finite-size saddle-point state:
|
||||
//LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT, Delta);
|
||||
LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
|
||||
spstate.Compute_All(true);
|
||||
|
||||
LiebLin_Bethe_State estate = spstate;
|
||||
if (whichDSF == 'o') estate = Remove_Particle_at_Center (spstate);
|
||||
else if (whichDSF == 'g') estate = Add_Particle_at_Center (spstate);
|
||||
if (whichDSF != 'd') estate.Compute_All(true);
|
||||
cout << estate << endl;
|
||||
Vect<int> OriginIx2 = estate.Ix2;
|
||||
|
||||
int Ix2old, Ix2new;
|
||||
int again = 0;
|
||||
string label_req;
|
||||
do {
|
||||
cout << "Substitute Ix2: which for which ?" << endl;
|
||||
cin >> Ix2old >> Ix2new;
|
||||
for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new;
|
||||
estate.Ix2.QuickSort();
|
||||
//cout << "Which label should the exc state be set to?" << endl;
|
||||
//cin >> label_req;
|
||||
//estate.Set_to_Label(label_req, OriginIx2);
|
||||
estate.Compute_All(false);
|
||||
cout << spstate << endl;
|
||||
cout << estate;
|
||||
if (whichDSF == 'd')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Density_ME(spstate, estate))) << endl;
|
||||
else if (whichDSF == 'o')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(estate, spstate))) << endl;
|
||||
else if (whichDSF == 'g')
|
||||
cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(spstate, estate))) << endl;
|
||||
|
||||
cout << "Another try ? (1 == yes, 0 == no)" << endl;
|
||||
again = 1;
|
||||
cin >> again;
|
||||
} while (again != 0);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Data_Daemon.cc
|
||||
|
||||
Purpose: Produces sets of data files for correlations.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 11) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Data_Daemon executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int_max \t\t Largest value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "int Nc \t\t number of steps in interaction value" << endl;
|
||||
cout << "int cfact \t\t dividing factor (each new interaction value if 1/cfact times the previous)" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Max_Hrs \t\t Allowed computational time: (in hours)" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
int ia = 1;
|
||||
char whichDSF = *argv[ia++];
|
||||
DP c_int_max = atof(argv[ia++]);
|
||||
int Nc = atoi(argv[ia++]);
|
||||
int cfact = atoi(argv[ia++]);
|
||||
DP L = atof(argv[ia++]);
|
||||
int N = atoi(argv[ia++]);
|
||||
int iKmin = atoi(argv[ia++]);
|
||||
int iKmax = atoi(argv[ia++]);
|
||||
DP kBT = atof(argv[ia++]);
|
||||
int Max_Hrs = atoi(argv[ia++]);
|
||||
|
||||
// Individual computations are split into chuncks of Max_Hrs/(Nc * 4)
|
||||
//int Max_Secs = (Max_Hrs * 900)/Nc;
|
||||
int Max_Secs = (Max_Hrs * 2700)/Nc; // to minimize wrapping up & restarting time
|
||||
|
||||
cout << "Data daemon will use chunks of " << Max_Secs << " seconds." << endl;
|
||||
|
||||
//clock_t StartTime = clock();
|
||||
double StartTime = omp_get_wtime();
|
||||
|
||||
//clock_t ActualTime = StartTime;
|
||||
double ActualTime = omp_get_wtime();
|
||||
|
||||
DP c_int;
|
||||
DP target_sumrule = 1.0;
|
||||
|
||||
//while (double(ActualTime - StartTime)/CLOCKS_PER_SEC < double(3600 * Max_Hrs - Max_Secs)) {
|
||||
while (ActualTime - StartTime < double(3600 * Max_Hrs - Max_Secs)) {
|
||||
|
||||
Vect<DP> srsat(0.0, Nc);
|
||||
Vect<bool> refine(false, Nc);
|
||||
DP srmin = 1.0;
|
||||
int icmin = 0;
|
||||
|
||||
// Determine which correlation has the worst sum rule:
|
||||
for (int ic = 0; ic < Nc; ++ic) {
|
||||
c_int = c_int_max/pow(cfact, ic);
|
||||
stringstream SRC_stringstream; string SRC_string;
|
||||
Data_File_Name (SRC_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
SRC_stringstream << ".src";
|
||||
SRC_string = SRC_stringstream.str(); const char* SRC_Cstr = SRC_string.c_str();
|
||||
|
||||
fstream srcfile;
|
||||
srcfile.open(SRC_Cstr, fstream::in);
|
||||
if (srcfile.fail()) {
|
||||
srsat[ic] = 0.0;
|
||||
refine[ic] = false;
|
||||
}
|
||||
else {
|
||||
srcfile >> srsat[ic];
|
||||
refine[ic] = true;
|
||||
}
|
||||
if (srsat[ic] < srmin) {
|
||||
srmin = srsat[ic];
|
||||
icmin = ic;
|
||||
}
|
||||
srcfile.close();
|
||||
|
||||
} // for ic
|
||||
|
||||
cout << "srsat min found: " << srmin << "\t for c = " << c_int_max/pow(cfact, icmin) << ". Now refining this."
|
||||
//<< " Time left: " << 3600* Max_Hrs - (ActualTime - StartTime)/CLOCKS_PER_SEC << " seconds." << endl;
|
||||
<< " Time left: " << 3600* Max_Hrs - (ActualTime - StartTime) << " seconds." << endl;
|
||||
|
||||
// Improve the icmin calculation by one chunk:
|
||||
Scan_LiebLin (whichDSF, c_int_max/pow(cfact, icmin), L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine[icmin]);
|
||||
|
||||
//ActualTime = clock();
|
||||
ActualTime = omp_get_wtime();
|
||||
|
||||
} // while there is time
|
||||
|
||||
cout << "Wrapping up, time's up." << endl;
|
||||
|
||||
} // else if arguments given OK
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Data_Daemon_Nscaling.cc
|
||||
|
||||
Purpose: Produces sets of data files for correlations, increasing system size at fixed c and momentum window.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Data_Daemon_Nscaling executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
//cout << "int Nc \t\t number of steps in interaction value" << endl;
|
||||
cout << "int Nstep \t\t\t Steps to be taken in number of particles: use positive integer values only. Filling will be set to 1 (L == N)" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over (in units of N == Nstep): recommended values: 0 and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "int Max_minutes \t\t Allowed computational time: (in minutes)" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
int ia = 1;
|
||||
char whichDSF = *argv[ia++];
|
||||
DP c_int = atof(argv[ia++]);
|
||||
int Nstep = atoi(argv[ia++]);
|
||||
int iKmin_Nstep = atoi(argv[ia++]);
|
||||
int iKmax_Nstep = atoi(argv[ia++]);
|
||||
DP kBT = atof(argv[ia++]);
|
||||
DP target_sumrule = atof(argv[ia++]);
|
||||
int Max_minutes = atoi(argv[ia++]);
|
||||
|
||||
|
||||
//clock_t StartTime = clock();
|
||||
double StartTime = omp_get_wtime();
|
||||
|
||||
//clock_t ActualTime = StartTime;
|
||||
double ActualTime = omp_get_wtime();
|
||||
|
||||
int Secs_left = 60* Max_minutes;
|
||||
|
||||
int iN = 0;
|
||||
|
||||
while (Secs_left > 0) {
|
||||
|
||||
iN += 1;
|
||||
int N = Nstep * iN;
|
||||
DP L = N;
|
||||
int iKmin = iKmin_Nstep * iN;
|
||||
int iKmax = iKmax_Nstep * iN;
|
||||
DP srsat = 0.0;
|
||||
bool refine = false;
|
||||
|
||||
stringstream SRC_stringstream; string SRC_string;
|
||||
Data_File_Name (SRC_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
SRC_stringstream << ".src";
|
||||
SRC_string = SRC_stringstream.str(); const char* SRC_Cstr = SRC_string.c_str();
|
||||
|
||||
fstream srcfile;
|
||||
srcfile.open(SRC_Cstr, fstream::in);
|
||||
if (srcfile.fail()) {
|
||||
srsat = 0.0;
|
||||
refine = false;
|
||||
}
|
||||
else {
|
||||
srcfile >> srsat;
|
||||
refine = true;
|
||||
}
|
||||
srcfile.close();
|
||||
|
||||
// Improve the icmin calculation by one chunk:
|
||||
Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Secs_left, target_sumrule, refine);
|
||||
|
||||
ActualTime = clock();
|
||||
|
||||
//Secs_left = int(60*Max_minutes - double(ActualTime - StartTime)/CLOCKS_PER_SEC);
|
||||
Secs_left = int(60*Max_minutes - (ActualTime - StartTime));
|
||||
|
||||
cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl;
|
||||
|
||||
} // while there is time
|
||||
|
||||
} // else if arguments given OK
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Fourier_to_Qsqx.cc
|
||||
|
||||
Purpose: Compute the Q(x)^2 expectation value for LiebLin, where Q(x) = \int_0^x dx \rho(x).
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Fourier_to_Qsqx executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 9), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int Npts_x = atoi(argv[8]);
|
||||
// Force Npts_x
|
||||
//Npts_x = L;
|
||||
|
||||
if (whichDSF != 'd') JSCerror("Must use whichDSF == d in LiebLin_Fourier_ssf_to_Qsqx");
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(RAW_Cstr);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << RAW_Cstr << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
// We also read the f-sumrule file, to correct for missing intensity.
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
FSR_stringstream << prefix << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
ifstream FSR_infile;
|
||||
FSR_infile.open(FSR_Cstr);
|
||||
if (FSR_infile.fail()) {
|
||||
cout << FSR_Cstr << endl;
|
||||
JSCerror("Could not open FSR_infile... ");
|
||||
}
|
||||
|
||||
stringstream SFT_stringstream; string SFT_string;
|
||||
SFT_stringstream << prefix << ".Qsqx";
|
||||
SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str();
|
||||
ofstream SFT_outfile;
|
||||
SFT_outfile.open(SFT_Cstr);
|
||||
if (SFT_outfile.fail()) JSCerror("Could not open SFT_outfile... ");
|
||||
|
||||
// First compute the static structure factor from the RAW data:
|
||||
|
||||
Vect_DP SSF(0.0, iKmax - iKmin + 1);
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
if (iK >= iKmin && iK <= iKmax) {
|
||||
SSF[iK - iKmin] += FF * FF;
|
||||
}
|
||||
}
|
||||
RAW_infile.close();
|
||||
|
||||
// Reset proper normalization:
|
||||
DP normalization = twoPI * L;
|
||||
for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) SSF[iK] *= normalization/twoPI; // twoPI from integral over omega
|
||||
|
||||
|
||||
// Now define real-space coordinates: between 0 and L/2
|
||||
Vect_DP xlattice(Npts_x);
|
||||
for (int i = 0; i < Npts_x; ++i) xlattice[i] = (i + 0.5) * 0.5* L/Npts_x;
|
||||
|
||||
// Now the correlation at x:
|
||||
Vect_DP FT(0.0, Npts_x);
|
||||
|
||||
DP pioverL = PI/L;
|
||||
|
||||
// Fourier transform:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
for (int iK = 1; iK <= iKmax; ++iK) {
|
||||
FT[ix] += SSF[iK - iKmin] * pow(sin(pioverL * iK * xlattice[ix])/iK, 2.0);
|
||||
}
|
||||
// Reset proper normalization: 1/L from space FT,
|
||||
FT[ix] *= 2.0*L/(PI * PI);
|
||||
|
||||
// Outside of window iKmin, iKmax, we take the DSF to be a constant with delta function
|
||||
// at free energy k^2, so DSF = 2\pi N/L \delta(\omega - k^2) (to fit f-sumrule)
|
||||
// so SSF becomes N/L.
|
||||
// We thus need to correct above by adding
|
||||
// \frac{1}{L} \sum_{-\infty}^{iKmin - 1} SSF e^{ikx} + \frac{1}{L} \sum_{iKmax + 1}^\infty SSF e^{ikx}
|
||||
// Resumming carefully:
|
||||
//FTre[ix] += (sin(twopioverL * (iKmin - 0.5) * xlattice[ix]) - sin(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
//* N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
//FTim[ix] += (-cos(twopioverL * (iKmin - 0.5) * xlattice[ix]) + cos(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
//* N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
}
|
||||
|
||||
|
||||
// Output to file:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
if (ix > 0) SFT_outfile << endl;
|
||||
//SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix];
|
||||
SFT_outfile << xlattice[ix]/L << "\t" << FT[ix];
|
||||
}
|
||||
|
||||
SFT_outfile.close();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Fourier_to_t_equal_x.cc
|
||||
|
||||
Purpose: Fourier transform to static space correlator for LiebLin.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int Npts_t \t Number of points in time for the Fourier transform" << endl;
|
||||
cout << "DP t_max \t Max time to be used" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int Npts_t = atoi(argv[8]);
|
||||
DP t_max = atof(argv[9]);
|
||||
|
||||
// Momentum business: use symmetry
|
||||
if (iKmin != 0) JSCerror("LiebLin_Fourier_to_t_equal_x only implemented for raw files with iKmin == 0.");
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(RAW_Cstr);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << RAW_Cstr << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
// We also read the f-sumrule file, to correct for missing intensity.
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
FSR_stringstream << prefix << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
ifstream FSR_infile;
|
||||
FSR_infile.open(FSR_Cstr);
|
||||
if (FSR_infile.fail()) {
|
||||
cout << FSR_Cstr << endl;
|
||||
JSCerror("Could not open FSR_infile... ");
|
||||
}
|
||||
|
||||
stringstream SFT_stringstream; string SFT_string;
|
||||
SFT_stringstream << prefix << ".tft";
|
||||
SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str();
|
||||
ofstream SFT_outfile;
|
||||
SFT_outfile.open(SFT_Cstr);
|
||||
if (SFT_outfile.fail()) JSCerror("Could not open TFT_outfile... ");
|
||||
|
||||
// First compute the static structure factor from the RAW data:
|
||||
|
||||
Vect_DP TSF(0.0, Npts_t);
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
// Now define time coordinates: between 0 and t_max
|
||||
Vect_DP tlattice(Npts_t);
|
||||
for (int i = 0; i < Npts_t; ++i) tlattice[i] = (i + 0.5) * t_max/Npts_t;
|
||||
|
||||
// Now the correlation at t:
|
||||
Vect<complex<DP> > FT(0.0, Npts_t);
|
||||
Vect_DP FTre(0.0, Npts_t);
|
||||
Vect_DP FTim(0.0, Npts_t);
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
if (iK == 0)
|
||||
for (int it = 0; it < Npts_t; ++it)
|
||||
FT[it] += FF * FF * exp(II * omega * tlattice[it]);
|
||||
else
|
||||
for (int it = 0; it < Npts_t; ++it)
|
||||
FT[it] += 2.0 * FF * FF * exp(II * omega * tlattice[it]);
|
||||
}
|
||||
RAW_infile.close();
|
||||
|
||||
// Reset proper normalization:
|
||||
for (int it = 0; it < Npts_t; ++it) {
|
||||
FTre[it] = real(FT[it]);
|
||||
FTim[it] = imag(FT[it]);
|
||||
}
|
||||
|
||||
// Output to file:
|
||||
for (int it = 0; it < Npts_t; ++it) {
|
||||
if (it > 0) SFT_outfile << endl;
|
||||
SFT_outfile << tlattice[it] << "\t" << FTre[it] << "\t" << FTim[it];
|
||||
}
|
||||
|
||||
SFT_outfile.close();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Fourier_to_t_equal_x.cc
|
||||
|
||||
Purpose: Fourier transform to static space correlator for LiebLin.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
|
||||
//cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "RAW file name" << endl;
|
||||
cout << "int Npts_t \t Number of points in time for the Fourier transform" << endl;
|
||||
cout << "DP t_max \t Max time to be used" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 10), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
//DP kBT = atof(argv[7]);
|
||||
char* rawfilename = argv[7];
|
||||
int Npts_t = atoi(argv[8]);
|
||||
DP t_max = atof(argv[9]);
|
||||
|
||||
// Momentum business: use symmetry
|
||||
if (iKmin != 0) JSCerror("LiebLin_Fourier_to_t_equal_x only implemented for raw files with iKmin == 0.");
|
||||
|
||||
ifstream RAW_infile;
|
||||
//RAW_infile.open(RAW_Cstr);
|
||||
RAW_infile.open(rawfilename);
|
||||
if (RAW_infile.fail()) {
|
||||
//cout << RAW_Cstr << endl;
|
||||
cout << rawfilename << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
stringstream SFT_stringstream; string SFT_string;
|
||||
SFT_stringstream << rawfilename << "_tft";
|
||||
SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str();
|
||||
ofstream SFT_outfile;
|
||||
SFT_outfile.open(SFT_Cstr);
|
||||
if (SFT_outfile.fail()) JSCerror("Could not open TFT_outfile... ");
|
||||
|
||||
// First compute the static structure factor from the RAW data:
|
||||
|
||||
Vect_DP TSF(0.0, Npts_t);
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
// Now define time coordinates: between 0 and t_max
|
||||
Vect_DP tlattice(Npts_t);
|
||||
for (int i = 0; i < Npts_t; ++i) tlattice[i] = (i + 0.5) * t_max/Npts_t;
|
||||
|
||||
// Now the correlation at t:
|
||||
Vect<complex<DP> > FT(0.0, Npts_t);
|
||||
Vect_DP FTre(0.0, Npts_t);
|
||||
Vect_DP FTim(0.0, Npts_t);
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
if (iK == 0)
|
||||
for (int it = 0; it < Npts_t; ++it)
|
||||
FT[it] += FF * FF * exp(II * omega * tlattice[it]);
|
||||
else
|
||||
for (int it = 0; it < Npts_t; ++it)
|
||||
FT[it] += 2.0 * FF * FF * exp(II * omega * tlattice[it]);
|
||||
}
|
||||
RAW_infile.close();
|
||||
|
||||
// Reset proper normalization:
|
||||
for (int it = 0; it < Npts_t; ++it) {
|
||||
FTre[it] = real(FT[it]);
|
||||
FTim[it] = imag(FT[it]);
|
||||
}
|
||||
|
||||
// Output to file:
|
||||
for (int it = 0; it < Npts_t; ++it) {
|
||||
if (it > 0) SFT_outfile << endl;
|
||||
SFT_outfile << tlattice[it] << "\t" << FTre[it] << "\t" << FTim[it];
|
||||
}
|
||||
|
||||
SFT_outfile.close();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Fourier_to_x_equal_t.cc
|
||||
|
||||
Purpose: Fourier transform to static space correlator for LiebLin.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 9), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int Npts_x = atoi(argv[8]);
|
||||
// Force Npts_x
|
||||
//Npts_x = L;
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(RAW_Cstr);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << RAW_Cstr << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
// We also read the f-sumrule file, to correct for missing intensity.
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
FSR_stringstream << prefix << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
ifstream FSR_infile;
|
||||
FSR_infile.open(FSR_Cstr);
|
||||
if (FSR_infile.fail()) {
|
||||
cout << FSR_Cstr << endl;
|
||||
JSCerror("Could not open FSR_infile... ");
|
||||
}
|
||||
|
||||
stringstream SFT_stringstream; string SFT_string;
|
||||
SFT_stringstream << prefix << ".sft";
|
||||
SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str();
|
||||
ofstream SFT_outfile;
|
||||
SFT_outfile.open(SFT_Cstr);
|
||||
if (SFT_outfile.fail()) JSCerror("Could not open SFT_outfile... ");
|
||||
|
||||
// First compute the static structure factor from the RAW data:
|
||||
|
||||
Vect_DP SSF(0.0, iKmax - iKmin + 1);
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
if (iK >= iKmin && iK <= iKmax) {
|
||||
SSF[iK - iKmin] += FF * FF;
|
||||
}
|
||||
}
|
||||
RAW_infile.close();
|
||||
|
||||
// Reset proper normalization:
|
||||
DP normalization = twoPI * L;
|
||||
for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) SSF[iK] *= normalization/twoPI; // twoPI from integral over omega
|
||||
|
||||
// We now refine the SSF in the following way.
|
||||
// First, we read off the f-sumrule saturation from the FSR file.
|
||||
// Then, we put back the missing weight, assuming that it lives
|
||||
// on the free k^2 dispersion relation (so the DSF is then simply 2\pi N/L \delta(\omega - k^2)).
|
||||
|
||||
Vect_DP FSRsaturated(0.0, iKmax - iKmin + 1);
|
||||
int dummyint;
|
||||
DP dummy;
|
||||
for (int i = iKmin; i <= iKmax; ++i)
|
||||
FSR_infile >> dummyint >> FSRsaturated[i - iKmin] >> dummy;
|
||||
|
||||
FSR_infile.close();
|
||||
|
||||
// Now correct the SSF by the missing piece:
|
||||
//for (int iK = iKmin; iK <= iKmax; ++iK)
|
||||
//SSF[iK - iKmin] += (1.0 - FSRsaturated[iK - iKmin]) * N/L;
|
||||
|
||||
//cout << FSRsaturated << endl;
|
||||
|
||||
//cout << SSF << endl;
|
||||
|
||||
// Now define real-space coordinates: between 0 and L
|
||||
Vect_DP xlattice(Npts_x);
|
||||
for (int i = 0; i < Npts_x; ++i) xlattice[i] = (i + 0.5) * L/Npts_x;
|
||||
|
||||
// Now the correlation at x:
|
||||
Vect_DP FTre(0.0, Npts_x);
|
||||
Vect_DP FTim(0.0, Npts_x);
|
||||
|
||||
DP twopioverL = twoPI/L;
|
||||
|
||||
// Fourier transform:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
for (int iK = iKmin; iK <= iKmax; ++iK) {
|
||||
FTre[ix] += SSF[iK - iKmin] * cos(twopioverL * iK * xlattice[ix]);
|
||||
FTim[ix] += SSF[iK - iKmin] * sin(twopioverL * iK * xlattice[ix]);
|
||||
}
|
||||
// Reset proper normalization: 1/L from space FT,
|
||||
FTre[ix] /= L;
|
||||
FTim[ix] /= L;
|
||||
|
||||
// Outside of window iKmin, iKmax, we take the DSF to be a constant with delta function
|
||||
// at free energy k^2, so DSF = 2\pi N/L \delta(\omega - k^2) (to fit f-sumrule)
|
||||
// so SSF becomes N/L.
|
||||
// We thus need to correct above by adding
|
||||
// \frac{1}{L} \sum_{-\infty}^{iKmin - 1} SSF e^{ikx} + \frac{1}{L} \sum_{iKmax + 1}^\infty SSF e^{ikx}
|
||||
// Resumming carefully:
|
||||
if (whichDSF == 'd') {
|
||||
FTre[ix] += (sin(twopioverL * (iKmin - 0.5) * xlattice[ix]) - sin(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
* N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
FTim[ix] += (-cos(twopioverL * (iKmin - 0.5) * xlattice[ix]) + cos(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
* N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
}
|
||||
}
|
||||
|
||||
// Since iKmax and iKmin are finite, we need to average over an interval of
|
||||
// deltax such that (2\pi/L) iKmax deltax = 2\pi, with deltax == deltaix * L/Npts_x
|
||||
// so deltaix = (Npts_x/L) * (L/iKmax)
|
||||
/*
|
||||
int deltaix = 0*int(Npts_x/(2.0*iKmax));
|
||||
cout << "deltaix = " << deltaix << endl;
|
||||
|
||||
Vect_DP FTreavg(0.0, Npts_x);
|
||||
Vect_DP FTimavg(0.0, Npts_x);
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
for (int ix2 = -deltaix; ix2 < deltaix; ++ix2) {
|
||||
FTreavg[ix] += FTre[JSC::min(JSC::max(0, ix + ix2), Npts_x - 1)];
|
||||
FTimavg[ix] += FTim[JSC::min(JSC::max(0, ix + ix2), Npts_x - 1)];
|
||||
}
|
||||
FTreavg[ix] /= (2*deltaix + 1);
|
||||
FTimavg[ix] /= (2*deltaix + 1);
|
||||
}
|
||||
*/
|
||||
if (whichDSF == 'd') cout << "g2(0) = dE0_dc/L = " << LiebLin_dE0_dc (c_int, L, N)/L << "\t" << LiebLin_dE0_dc (c_int, 2.0*L, 2*N)/(2.0*L) << endl;
|
||||
|
||||
// Output to file:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
if (ix > 0) SFT_outfile << endl;
|
||||
//SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix];
|
||||
SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix];
|
||||
}
|
||||
|
||||
SFT_outfile.close();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_Fourier_to_x_equal_t.cc
|
||||
|
||||
Purpose: Fourier transform to static space correlator for LiebLin.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
|
||||
//cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "RAW file name" << endl;
|
||||
cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 9), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
//DP kBT = atof(argv[7]);
|
||||
char* rawfilename = argv[7];
|
||||
int Npts_x = atoi(argv[8]);
|
||||
// Force Npts_x
|
||||
//Npts_x = L;
|
||||
|
||||
//stringstream filenameprefix;
|
||||
//Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
//string prefix = filenameprefix.str();
|
||||
|
||||
//stringstream RAW_stringstream; string RAW_string;
|
||||
//RAW_stringstream << prefix << ".raw";
|
||||
//RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
ifstream RAW_infile;
|
||||
//RAW_infile.open(RAW_Cstr);
|
||||
RAW_infile.open(rawfilename);
|
||||
if (RAW_infile.fail()) {
|
||||
//cout << RAW_Cstr << endl;
|
||||
cout << rawfilename << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
// Define the output file name: use the RAW file name but with different suffix
|
||||
|
||||
stringstream SFT_stringstream; string SFT_string;
|
||||
SFT_stringstream << rawfilename << "_sft";
|
||||
SFT_string = SFT_stringstream.str(); const char* SFT_Cstr = SFT_string.c_str();
|
||||
ofstream SFT_outfile;
|
||||
SFT_outfile.open(SFT_Cstr);
|
||||
if (SFT_outfile.fail()) JSCerror("Could not open SFT_outfile... ");
|
||||
|
||||
// First compute the static structure factor from the RAW data:
|
||||
|
||||
Vect_DP SSF(0.0, iKmax - iKmin + 1);
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP FF;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
RAW_infile >> omega >> iK >> FF >> dev >> label;
|
||||
if (iK >= iKmin && iK <= iKmax) {
|
||||
SSF[iK - iKmin] += FF * FF;
|
||||
}
|
||||
}
|
||||
RAW_infile.close();
|
||||
|
||||
// Reset proper normalization:
|
||||
DP normalization = twoPI * L;
|
||||
for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) SSF[iK] *= normalization/twoPI; // twoPI from integral over omega
|
||||
|
||||
|
||||
// Now define real-space coordinates: between 0 and L
|
||||
Vect_DP xlattice(Npts_x);
|
||||
for (int i = 0; i < Npts_x; ++i) xlattice[i] = (i + 0.5) * L/Npts_x;
|
||||
|
||||
// Now the correlation at x:
|
||||
Vect_DP FTre(0.0, Npts_x);
|
||||
Vect_DP FTim(0.0, Npts_x);
|
||||
|
||||
DP twopioverL = twoPI/L;
|
||||
|
||||
// Fourier transform:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
for (int iK = iKmin; iK <= iKmax; ++iK) {
|
||||
FTre[ix] += SSF[iK - iKmin] * cos(twopioverL * iK * xlattice[ix]);
|
||||
FTim[ix] += SSF[iK - iKmin] * sin(twopioverL * iK * xlattice[ix]);
|
||||
}
|
||||
// Reset proper normalization: 1/L from space FT,
|
||||
FTre[ix] /= L;
|
||||
FTim[ix] /= L;
|
||||
|
||||
// Outside of window iKmin, iKmax, we take the DSF to be a constant with delta function
|
||||
// at free energy k^2, so DSF = 2\pi N/L \delta(\omega - k^2) (to fit f-sumrule)
|
||||
// so SSF becomes N/L.
|
||||
// We thus need to correct above by adding
|
||||
// \frac{1}{L} \sum_{-\infty}^{iKmin - 1} SSF e^{ikx} + \frac{1}{L} \sum_{iKmax + 1}^\infty SSF e^{ikx}
|
||||
// Resumming carefully:
|
||||
//if (whichDSF == 'd') {
|
||||
//FTre[ix] += (sin(twopioverL * (iKmin - 0.5) * xlattice[ix]) - sin(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
// * N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
//FTim[ix] += (-cos(twopioverL * (iKmin - 0.5) * xlattice[ix]) + cos(twopioverL * (iKmax + 0.5) * xlattice[ix]))
|
||||
// * N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
// Output to file:
|
||||
for (int ix = 0; ix < Npts_x; ++ix) {
|
||||
if (ix > 0) SFT_outfile << endl;
|
||||
//SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix];
|
||||
SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix];
|
||||
}
|
||||
|
||||
SFT_outfile.close();
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_DSF_tester.cc
|
||||
|
||||
Purpose: allows for Ix2 manipulations (user-prompted) for LiebLin gas
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 8) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 6), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int Nl = atoi(argv[5]);
|
||||
//int Nr = N - Nl;
|
||||
int DIl = atoi(argv[6]);
|
||||
int DIr = atoi(argv[7]);
|
||||
|
||||
if (whichDSF != 'd') JSCerror("Other options not implemented yet in LiebLin_Moses_tester");
|
||||
|
||||
// Define the Moses state:
|
||||
LiebLin_Bethe_State MosesState (c_int, L, N);
|
||||
|
||||
// Split the sea:
|
||||
for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] -= 2 * DIl;
|
||||
for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
|
||||
|
||||
MosesState.Compute_All (true);
|
||||
|
||||
LiebLin_Bethe_State estate = MosesState;
|
||||
cout << MosesState;
|
||||
|
||||
int Ix2old, Ix2new;
|
||||
int again = 0;
|
||||
do {
|
||||
cout << "Substitute Ix2: which for which ?" << endl;
|
||||
cin >> Ix2old >> Ix2new;
|
||||
for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new;
|
||||
estate.Compute_All(false);
|
||||
cout << estate;
|
||||
cout << setprecision(16) << "omega = " << estate.E - MosesState.E << "\t" << exp(real(ln_Density_ME(MosesState, estate))) << endl;
|
||||
cout << "Another try ? (0 == no)" << endl;
|
||||
cin >> again;
|
||||
} while (again != 0);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_RAW_File_stats.cc
|
||||
|
||||
Purpose: Analyzes the distribution of matrix element values in a RAW file,
|
||||
to help with optimization of the scanning procedure.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 9) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of LiebLin_RAW_File_Stats executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter: use positive real values only" << endl;
|
||||
cout << "DP L \t\t\t Length of the system: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Number of particles: use positive integer values only" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: -2*N and 2*N" << endl;
|
||||
cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
|
||||
cout << "int Aggregate size" << endl;
|
||||
}
|
||||
|
||||
else { // (argc == 9), correct nr of arguments
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int AgSize = atoi(argv[8]);
|
||||
|
||||
if (AgSize < 2) JSCerror("Give an aggregate size > 1 in LiebLin_RAW_File_Stats.");
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
Data_File_Name (RAW_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
RAW_stringstream << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(RAW_Cstr);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << RAW_Cstr << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
stringstream STAT_stringstream; string STAT_string;
|
||||
Data_File_Name (STAT_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
STAT_stringstream << ".stat";
|
||||
STAT_string = STAT_stringstream.str(); const char* STAT_Cstr = STAT_string.c_str();
|
||||
|
||||
ofstream STATfile;
|
||||
STATfile.open(STAT_Cstr);
|
||||
if (STATfile.fail()) {
|
||||
cout << STAT_Cstr << endl; JSCerror("Could not open STATfile.");
|
||||
}
|
||||
|
||||
LiebLin_Bethe_State AveragingState = Canonical_Saddle_Point_State (c_int, L, N, whichDSF == 'Z' ? 0.0 : kBT);
|
||||
|
||||
DP Chem_Pot = Chemical_Potential (AveragingState);
|
||||
//DP sumrule_factor = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, fixed_iK, iKneeded);
|
||||
Vect<DP> sumrule_factor(iKmax - iKmin + 1);
|
||||
for (int ik = 0; ik < iKmax - iKmin + 1; ++ik)
|
||||
sumrule_factor[ik] = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, ik, ik);
|
||||
// Normalize by total number of considered momenta
|
||||
DP correction_factor = 1.0/(iKmax - iKmin + 1);
|
||||
if (iKmin <= 0 && iKmax >= 0 && whichDSF == 'd') { // correct for fact that RhoRho is 0 at k = 0
|
||||
sumrule_factor[0] = 0.0;
|
||||
correction_factor = 1.0/(iKmax - iKmin);
|
||||
}
|
||||
|
||||
for (int ik = 0; ik < iKmax - iKmin + 1; ++ik) sumrule_factor[ik] *= correction_factor;
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP ME;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
int nread = 0;
|
||||
|
||||
DP srcont = 0.0;
|
||||
DP abssrcont = 0.0;
|
||||
DP maxsrcont = 0.0;
|
||||
DP totsrcont = 0.0;
|
||||
DP accumulatedsrcont = 0.0;
|
||||
int naccounted = 0;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
|
||||
RAW_infile >> omega >> iK >> ME >> dev >> label;
|
||||
nread++;
|
||||
|
||||
if (iK >= iKmin && iK <= iKmax) {
|
||||
srcont = omega * ME * ME * sumrule_factor[iK - iKmin];
|
||||
abssrcont = fabs(srcont);
|
||||
maxsrcont = JSC::max(maxsrcont, abssrcont);
|
||||
totsrcont += srcont;
|
||||
accumulatedsrcont += srcont;
|
||||
naccounted++;
|
||||
}
|
||||
|
||||
if (naccounted >= AgSize) {
|
||||
STATfile << nread << "\t" << maxsrcont << "\t" << totsrcont/AgSize << "\t" << totsrcont/(AgSize * (maxsrcont > 0.0 ? maxsrcont : 1.0)) << "\t" << accumulatedsrcont << endl;
|
||||
naccounted = 0;
|
||||
maxsrcont = 0.0;
|
||||
totsrcont = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
RAW_infile.close();
|
||||
STATfile.close();
|
||||
}
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_TBA.cc
|
||||
|
||||
Purpose: solves the TBA equations for Lieb-Liniger
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
||||
//if (argc != 7) JSCerror("Wrong number of arguments to 2CBG_ThLim executable. Use c(best to set to 1), nbar, ebar, req_diff, Max_Secs, bool Save_data (0 == false).");
|
||||
if (argc != 6) JSCerror("Wrong number of arguments. Use c(best to set to 1), mu, kBT, req_diff, Max_Secs");
|
||||
|
||||
DP c_int = atof(argv[1]);
|
||||
DP mu = atof(argv[2]);
|
||||
DP kBT = atof(argv[3]);
|
||||
DP req_diff = atof(argv[4]);
|
||||
int Max_Secs = atoi(argv[5]);
|
||||
|
||||
if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
|
||||
if (kBT <= 0.0) JSCerror("Negative T ? Not for the LiebLin gas.");
|
||||
if (Max_Secs < 10) JSCerror("Give more time.");
|
||||
|
||||
//cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
|
||||
|
||||
LiebLin_TBA_Solution solution(c_int, mu, kBT, req_diff, Max_Secs);
|
||||
|
||||
|
||||
cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_TBA_fixed_nbar.cc
|
||||
|
||||
Purpose: solves the TBA equations for Lieb-Liniger
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
||||
//if (argc != 7) JSCerror("Wrong number of arguments to 2CBG_ThLim executable. Use c(best to set to 1), nbar, ebar, req_diff, Max_Secs, bool Save_data (0 == false).");
|
||||
if (argc != 6) JSCerror("Wrong number of arguments. Use c(best to set to 1), nbar, kBT, req_diff, Max_Secs");
|
||||
|
||||
DP c_int = atof(argv[1]);
|
||||
DP nbar = atof(argv[2]);
|
||||
DP kBT = atof(argv[3]);
|
||||
DP req_diff = atof(argv[4]);
|
||||
int Max_Secs = atoi(argv[5]);
|
||||
|
||||
if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
|
||||
if (kBT <= 0.0) JSCerror("Negative T ? Not for the LiebLin gas.");
|
||||
if (Max_Secs < 10) JSCerror("Give more time.");
|
||||
|
||||
//cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
|
||||
|
||||
LiebLin_TBA_Solution solution = LiebLin_TBA_Solution_fixed_nbar (c_int, nbar, kBT, req_diff, Max_Secs);
|
||||
|
||||
cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: LiebLin_TBA_fixed_nbar_ebar.cc
|
||||
|
||||
Purpose: solves the TBA equations for Lieb-Liniger
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 7) JSCerror("Wrong number of arguments. Use c(best to set to 1), nbar, ebar, req_diff, Max_Secs, bool Save_data (0 == false).");
|
||||
|
||||
DP c_int = atof(argv[1]);
|
||||
DP nbar = atof(argv[2]);
|
||||
DP ebar = atof(argv[3]);
|
||||
DP req_diff = atof(argv[4]);
|
||||
int Max_Secs = atoi(argv[5]);
|
||||
bool Save_data = bool(atoi(argv[6]));
|
||||
|
||||
if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
|
||||
if (Max_Secs < 10) JSCerror("Give more time.");
|
||||
|
||||
//cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
|
||||
|
||||
LiebLin_TBA_Solution solution = LiebLin_TBA_Solution_fixed_nbar_ebar(c_int, nbar, ebar, req_diff, Max_Secs);
|
||||
|
||||
cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: ODSLF_DSF.cc
|
||||
|
||||
Purpose: main function for ABACUS++ for spinless fermions related to Heisenberg spin-1/2 chain
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 10) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << "Usage of ODSLF_DSF executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: m for S- S+, z for Sz Sz, p for S+ S-." << endl;
|
||||
cout << "DP Delta \t\t Value of the anisotropy: use positive real values only" << endl;
|
||||
cout << "int N \t\t\t Length (number of sites) of the system: use positive even integer values only" << endl;
|
||||
cout << "int M \t\t\t Number of down spins: use positive integer values between 1 and N/2" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over: recommended values: 0 and N" << endl;
|
||||
cout << "int Max_Secs \t\t Allowed computational time: (in seconds)" << endl;
|
||||
cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
|
||||
cout << "bool refine \t\t Is this a refinement of a earlier calculations ? (0 == false, 1 == true)" << endl;
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "ODSLF_DSF z 1.0 100 40 0 100 600 1.0 0" << endl << endl;
|
||||
}
|
||||
|
||||
else if (argc == 10) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
int Max_Secs = atoi(argv[7]);
|
||||
DP target_sumrule = atof(argv[8]);
|
||||
bool refine = (atoi(argv[9]) == 1);
|
||||
|
||||
Scan_ODSLF (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
else JSCerror("Wrong number of arguments to ODSLF_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Sort_RAW_File.cc
|
||||
|
||||
Purpose: produce a sorted .raw file.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 4) {
|
||||
cout << "Arguments needed: rawfile, whichDSF, whichsorting." << endl;
|
||||
JSCerror("");
|
||||
}
|
||||
|
||||
const char* rawfilename = argv[1];
|
||||
char whichDSF = *argv[2];
|
||||
char whichsorting = *argv[3];
|
||||
|
||||
|
||||
//cout << rawfilename << "\t" << whichDSF << "\t" << whichsorting << endl;
|
||||
Sort_RAW_File (rawfilename, whichsorting, whichDSF);
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: RAW_File_stats.cc
|
||||
|
||||
Purpose: Analyzes the distribution of matrix element values in a RAW file,
|
||||
to help with optimization of the scanning procedure.
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
if (argc != 3) { // provide some info
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of RAW_File_Stats executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << endl << "string RAW file name" << endl;
|
||||
cout << "int Aggregate size" << endl;
|
||||
}
|
||||
|
||||
else { // correct nr of arguments
|
||||
const char* rawfilename = argv[1];
|
||||
int AgSize = atoi(argv[2]);
|
||||
|
||||
if (AgSize < 2) JSCerror("Give an aggregate size > 1 in LiebLin_RAW_File_Stats.");
|
||||
|
||||
ifstream RAW_infile;
|
||||
RAW_infile.open(rawfilename);
|
||||
if (RAW_infile.fail()) {
|
||||
cout << rawfilename << endl;
|
||||
JSCerror("Could not open RAW_infile... ");
|
||||
}
|
||||
|
||||
stringstream STAT_stringstream; string STAT_string;
|
||||
STAT_stringstream << rawfilename << "_AgS_" << AgSize << "_stat";
|
||||
STAT_string = STAT_stringstream.str(); const char* STAT_Cstr = STAT_string.c_str();
|
||||
|
||||
ofstream STATfile;
|
||||
STATfile.open(STAT_Cstr);
|
||||
if (STATfile.fail()) {
|
||||
cout << STAT_Cstr << endl; JSCerror("Could not open STATfile.");
|
||||
}
|
||||
|
||||
DP omega;
|
||||
int iK;
|
||||
DP ME;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
int nread = 0;
|
||||
|
||||
DP srcont = 0.0;
|
||||
DP abssrcont = 0.0;
|
||||
DP maxsrcont = 0.0;
|
||||
DP totsrcont = 0.0;
|
||||
DP accumulatedsrcont = 0.0;
|
||||
int naccounted = 0;
|
||||
|
||||
while (RAW_infile.peek() != EOF) {
|
||||
|
||||
RAW_infile >> omega >> iK >> ME >> dev >> label;
|
||||
nread++;
|
||||
|
||||
srcont = ME * ME;
|
||||
abssrcont = fabs(srcont);
|
||||
maxsrcont = JSC::max(maxsrcont, abssrcont);
|
||||
totsrcont += srcont;
|
||||
accumulatedsrcont += srcont;
|
||||
naccounted++;
|
||||
|
||||
if (naccounted >= AgSize) {
|
||||
STATfile << nread << "\t" << maxsrcont << "\t" << totsrcont/AgSize << "\t" << totsrcont/(AgSize * (maxsrcont > 0.0 ? maxsrcont : 1.0)) << "\t" << accumulatedsrcont << endl;
|
||||
naccounted = 0;
|
||||
maxsrcont = 0.0;
|
||||
totsrcont = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
RAW_infile.close();
|
||||
STATfile.close();
|
||||
}
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_Heis_DSF.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 13 && argc != 14) { // Print out instructions
|
||||
//if (strcmp(argv[1],"help") == 0) { // Output some instructions
|
||||
cout << "Usage of Smoothen_Heis_DSF executable: " << endl << endl;
|
||||
cout << "Provide arguments using one of the following options:" << endl << endl;
|
||||
cout << "1) (for general momenta) whichDSF Delta N M iKmin iKmax DiK kBT ommin ommax Nom gwidth" << endl << endl;
|
||||
cout << "2) (for fixed momentum) whichDSF Delta N M iKneeded ommin ommax Nom gwidth" << endl << endl;
|
||||
//else JSCerror("Incomprehensible arguments in Smoothen_Heis_DSF executable.");
|
||||
}
|
||||
|
||||
else if (argc == 13) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
int DiK = atoi(argv[7]);
|
||||
DP kBT = atof(argv[8]);
|
||||
DP ommin = atof(argv[9]);
|
||||
DP ommax = atof(argv[10]);
|
||||
int Nom = atoi(argv[11]);
|
||||
DP gwidth = atof(argv[12]);
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, Delta, N, M, iKmin, iKmax, kBT, 0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI;
|
||||
DP denom_sum_K = 1.0/N;
|
||||
|
||||
Write_K_File (N, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
|
||||
DP sumcheck;
|
||||
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, gwidth, normalization, denom_sum_K);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
else if (argc == 10) { // fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKneeded = atoi(argv[5]);
|
||||
DP ommin = atof(argv[6]);
|
||||
DP ommax = atof(argv[7]);
|
||||
int Nom = atoi(argv[8]);
|
||||
DP gwidth = atof(argv[9]);
|
||||
|
||||
bool fixed_iK = true;
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, Delta, N, M, fixed_iK, iKneeded, 0.0, 0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI;
|
||||
int iKmin = iKneeded;
|
||||
int iKmax = iKneeded;
|
||||
|
||||
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
//else JSCerror("Wrong number of arguments to Smoothen_Heis_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_LiebLin_DSF.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 13) { // Print out instructions
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
|
||||
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
|
||||
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
|
||||
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
|
||||
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Smoothen_LiebLin_DSF d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 13) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int DiK = atoi(argv[8]);
|
||||
DP ommin = atof(argv[9]);
|
||||
DP ommax = atof(argv[10]);
|
||||
int Nom = atoi(argv[11]);
|
||||
DP width = atof(argv[12]);
|
||||
|
||||
stringstream filenameprefix;
|
||||
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
DP denom_sum_K = L;
|
||||
|
||||
Write_K_File (L, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
|
||||
// We use the scaled width function as default:
|
||||
|
||||
DP sumcheck;
|
||||
//if (kBT < 0.1)
|
||||
//sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
|
||||
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
|
||||
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
|
||||
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
|
||||
}
|
||||
|
||||
/*
|
||||
else if (argc == 11) { // fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iK_UL = atoi(argv[5]);
|
||||
int iKneeded = atoi(argv[6]);
|
||||
DP ommin = atof(argv[7]);
|
||||
DP ommax = atof(argv[8]);
|
||||
int Nom = atoi(argv[9]);
|
||||
DP gwidth = atof(argv[10]);
|
||||
|
||||
//bool fixed_iK = true;
|
||||
//LiebLin_Bethe_State GroundState (c_int, L, N, iK_UL, 0LL);
|
||||
stringstream filenameprefix;
|
||||
//Data_File_Name (filenameprefix, whichDSF, fixed_iK, iKneeded, GroundState, GroundState);
|
||||
//Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 0.0);
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, iKneeded, iKneeded, 0.0);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
int iKmin = iKneeded;
|
||||
int iKmax = iKneeded;
|
||||
|
||||
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
//else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_LiebLin_DSF_GeneralState.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 13) { // Print out instructions
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
|
||||
//cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
|
||||
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
|
||||
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
|
||||
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
|
||||
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Smoothen_LiebLin_DSF d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 13) { // !fixed_iK
|
||||
int n = 1;
|
||||
char whichDSF = *argv[n++];
|
||||
DP c_int = atof(argv[n++]);
|
||||
DP L = atof(argv[n++]);
|
||||
int N = atoi(argv[n++]);
|
||||
char* Ix2filenameprefix = argv[n++];
|
||||
int iKmin = atoi(argv[n++]);
|
||||
int iKmax = atoi(argv[n++]);
|
||||
//DP kBT = atof(argv[7]);
|
||||
DP kBT = 0.0;
|
||||
int DiK = atoi(argv[n++]);
|
||||
DP ommin = atof(argv[n++]);
|
||||
DP ommax = atof(argv[n++]);
|
||||
int Nom = atoi(argv[n++]);
|
||||
DP width = atof(argv[n++]);
|
||||
|
||||
stringstream filenamestrstream;
|
||||
filenamestrstream << Ix2filenameprefix;
|
||||
string defaultScanStatename = filenamestrstream.str();
|
||||
|
||||
stringstream filenameprefix;
|
||||
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
|
||||
//Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, defaultScanStatename);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
DP denom_sum_K = L;
|
||||
|
||||
Write_K_File (L, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
|
||||
// We use the scaled width function as default:
|
||||
|
||||
DP sumcheck;
|
||||
//if (kBT < 0.1)
|
||||
//sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
|
||||
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
|
||||
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
|
||||
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
|
||||
}
|
||||
|
||||
/*
|
||||
else if (argc == 11) { // fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iK_UL = atoi(argv[5]);
|
||||
int iKneeded = atoi(argv[6]);
|
||||
DP ommin = atof(argv[7]);
|
||||
DP ommax = atof(argv[8]);
|
||||
int Nom = atoi(argv[9]);
|
||||
DP gwidth = atof(argv[10]);
|
||||
|
||||
//bool fixed_iK = true;
|
||||
//LiebLin_Bethe_State GroundState (c_int, L, N, iK_UL, 0LL);
|
||||
stringstream filenameprefix;
|
||||
//Data_File_Name (filenameprefix, whichDSF, fixed_iK, iKneeded, GroundState, GroundState);
|
||||
//Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 0.0);
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, iKneeded, iKneeded, 0.0);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
int iKmin = iKneeded;
|
||||
int iKmax = iKneeded;
|
||||
|
||||
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
|
||||
}
|
||||
*/
|
||||
|
||||
//else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_LiebLin_DSF_MosesState.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 15) { // Print out instructions
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Smoothen_LiebLin_DSF_MosesState executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
|
||||
cout << "int DIl \t\t shift of left sea as compared to its ground state position" << endl;
|
||||
cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
|
||||
//cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
|
||||
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
|
||||
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
|
||||
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
|
||||
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Smoothen_LiebLin_DSF_MosesState d 1.0 100.0 100 50 -30 40 0 200 1 0.0 10.0 500 2.0" << endl << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 15) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int Nl = atoi(argv[5]);
|
||||
//int Nr = N - Nl;
|
||||
int DIl = atoi(argv[6]);
|
||||
int DIr = atoi(argv[7]);
|
||||
int iKmin = atoi(argv[8]);
|
||||
int iKmax = atoi(argv[9]);
|
||||
//DP kBT = atof(argv[10]);
|
||||
DP kBT = 0.0;
|
||||
int DiK = atoi(argv[10]);
|
||||
DP ommin = atof(argv[11]);
|
||||
DP ommax = atof(argv[12]);
|
||||
int Nom = atoi(argv[13]);
|
||||
DP width = atof(argv[14]);
|
||||
|
||||
// Handy default name:
|
||||
stringstream defaultScanStatename_strstream;
|
||||
defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
|
||||
string defaultScanStatename = defaultScanStatename_strstream.str();
|
||||
|
||||
stringstream filenameprefix;
|
||||
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, defaultScanStatename);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
DP denom_sum_K = L;
|
||||
|
||||
Write_K_File (L, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
|
||||
// We use the scaled width function as default:
|
||||
|
||||
DP sumcheck;
|
||||
//if (kBT < 0.1)
|
||||
//sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
|
||||
sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
|
||||
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
|
||||
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
|
||||
}
|
||||
|
||||
//else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_LiebLin_DSF_Scaled.cc
|
||||
|
||||
Purpose: produces .dsfs and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 13) { // Print out instructions
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Smoothen_LiebLin_DSF_Scaled executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
|
||||
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
|
||||
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
|
||||
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
|
||||
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Smoothen_LiebLin_DSF d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 13) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
int DiK = atoi(argv[8]);
|
||||
DP ommin = atof(argv[9]);
|
||||
DP ommax = atof(argv[10]);
|
||||
int Nom = atoi(argv[11]);
|
||||
DP width = atof(argv[12]);
|
||||
|
||||
stringstream filenameprefix;
|
||||
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
//DP denom_sum_K = L;
|
||||
|
||||
Write_K_File (L, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
//cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
|
||||
// We use the scaled width function as default:
|
||||
|
||||
DP sumcheck;
|
||||
//if (kBT < 0.1)
|
||||
sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
|
||||
//sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
|
||||
//else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
|
||||
//cout << "Smoothing: sumcheck = " << sumcheck << endl;
|
||||
}
|
||||
|
||||
//else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS library.
|
||||
|
||||
Copyright (c).
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_LiebLin_DSF_over_Ensemble.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from an ensemble of .raw files
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 13) { // Print out instructions
|
||||
|
||||
cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
|
||||
cout << endl << "Usage of Smoothen_LiebLin_DSF_over_Ensemble executable: " << endl;
|
||||
cout << endl << "Provide the following arguments:" << endl << endl;
|
||||
cout << "char whichDSF \t\t Which structure factor should be calculated ? Options are: d for rho rho, g for psi psi{dagger}, o for psi{dagger} psi" << endl;
|
||||
cout << "DP c_int \t\t Value of the interaction parameter" << endl;
|
||||
cout << "DP L \t\t\t Length of the system" << endl;
|
||||
cout << "int N \t\t\t Number of particles" << endl;
|
||||
cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
|
||||
cout << "DP kBT \t\t Temperature" << endl;
|
||||
//cout << "int nstates \t\t\t Number of states considered in the ensemble" << endl;
|
||||
cout << "int DiK \t\t\t Window of iK over which DSF is averaged (DiK == 0 means a single iK is used; DiK == 1 means 3 are used (iK-1, iK, iK+1), etc.)" << endl;
|
||||
cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
|
||||
cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
|
||||
cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
|
||||
|
||||
cout << endl << "EXAMPLE: " << endl << endl;
|
||||
cout << "Smoothen_LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 13) {
|
||||
char whichDSF = *argv[1];
|
||||
DP c_int = atof(argv[2]);
|
||||
DP L = atof(argv[3]);
|
||||
int N = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP kBT = atof(argv[7]);
|
||||
//int nstates_req = atoi(argv[8]);
|
||||
int DiK = atoi(argv[8]);
|
||||
DP ommin = atof(argv[9]);
|
||||
DP ommax = atof(argv[10]);
|
||||
int Nom = atoi(argv[11]);
|
||||
DP width = atof(argv[12]);
|
||||
|
||||
stringstream filenameprefix;
|
||||
//void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
|
||||
Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI * L;
|
||||
DP denom_sum_K = L;
|
||||
|
||||
Write_K_File (L, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
|
||||
// Read the weights from the ensembles file:
|
||||
LiebLin_Diagonal_State_Ensemble ensemble;
|
||||
|
||||
stringstream ensfilestrstream;
|
||||
//ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
|
||||
ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
|
||||
string ensfilestr = ensfilestrstream.str();
|
||||
const char* ensfile_Cstr = ensfilestr.c_str();
|
||||
|
||||
ensemble.Load(c_int, L, N, ensfile_Cstr);
|
||||
|
||||
// Define the raw file names
|
||||
Vect<string> rawfilename(ensemble.nstates);
|
||||
|
||||
for (int ns = 0; ns < ensemble.nstates; ++ns) {
|
||||
// Define the raw input file name:
|
||||
stringstream filenameprefix;
|
||||
//Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, kBT, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
|
||||
Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);
|
||||
string prefix = filenameprefix.str();
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
//RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
rawfilename[ns] = RAW_stringstream.str();
|
||||
}
|
||||
|
||||
Smoothen_RAW_into_SF (prefix, rawfilename, ensemble.weight, iKmin, iKmax, DiK,
|
||||
ommin, ommax, Nom, width, normalization, denom_sum_K);
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: Smoothen_ODSLF_DSF.cc
|
||||
|
||||
Purpose: produces .dsf and .ssf files from a .raw file
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 10 && argc != 11) { // Print out instructions
|
||||
//if (strcmp(argv[1],"help") == 0) { // Output some instructions
|
||||
cout << "Usage of Smoothen_ODSLF_DSF executable: " << endl << endl;
|
||||
cout << "Provide arguments using one of the following options:" << endl << endl;
|
||||
cout << "1) (for general momenta) whichDSF Delta N M iKmin iKmax ommin ommax Nom gwidth" << endl << endl;
|
||||
cout << "2) (for fixed momentum) whichDSF Delta N M iKneeded ommin ommax Nom gwidth" << endl << endl;
|
||||
//else JSCerror("Incomprehensible arguments in Smoothen_ODSLF_DSF executable.");
|
||||
}
|
||||
|
||||
else if (argc == 11) { // !fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKmin = atoi(argv[5]);
|
||||
int iKmax = atoi(argv[6]);
|
||||
DP ommin = atof(argv[7]);
|
||||
DP ommax = atof(argv[8]);
|
||||
int Nom = atoi(argv[9]);
|
||||
DP gwidth = atof(argv[10]);
|
||||
|
||||
stringstream filenameprefix;
|
||||
ODSLF_Data_File_Name (filenameprefix, whichDSF, Delta, N, M, iKmin, iKmax, 0.0, 0);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI;
|
||||
|
||||
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
|
||||
|
||||
Write_K_File (N, iKmin, iKmax);
|
||||
Write_Omega_File (Nom, ommin, ommax);
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 10) { // fixed_iK
|
||||
char whichDSF = *argv[1];
|
||||
DP Delta = atof(argv[2]);
|
||||
int N = atoi(argv[3]);
|
||||
int M = atoi(argv[4]);
|
||||
int iKneeded = atoi(argv[5]);
|
||||
DP ommin = atof(argv[6]);
|
||||
DP ommax = atof(argv[7]);
|
||||
int Nom = atoi(argv[8]);
|
||||
DP gwidth = atof(argv[9]);
|
||||
|
||||
bool fixed_iK = true;
|
||||
|
||||
stringstream filenameprefix;
|
||||
Data_File_Name (filenameprefix, whichDSF, Delta, N, M, fixed_iK, iKneeded, 0.0, 0);
|
||||
string prefix = filenameprefix.str();
|
||||
|
||||
DP normalization = twoPI;
|
||||
int iKmin = iKneeded;
|
||||
int iKmax = iKneeded;
|
||||
|
||||
cout << "Smoothing: sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
|
||||
}
|
||||
|
||||
else JSCerror("Wrong number of arguments to Smoothen_Heis_DSF executable.");
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: ABACUS++G_2_testing.cc
|
||||
|
||||
Purpose: testing of ABACUS++2
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
int main( int argc, char* argv[])
|
||||
{
|
||||
if (!(argc == 3 || argc == 5)) { // provide some info
|
||||
cout << endl << "This code computes the (1/N) (-1)^j S^z_j on-site staggered magnetization for XXZ_gpd in zero field." << endl;
|
||||
cout << "First option: provide two arguments: anisotropy Delta (> 1) and system size N (even)." << endl;
|
||||
cout << "Second option: provide five arguments: system size N (even), Delta min, Delta max, NDelta." << endl;
|
||||
cout << "The output is Delta, N, stag mag, energy gap." << endl;
|
||||
JSCerror("");
|
||||
}
|
||||
else if (argc == 3) {
|
||||
DP Delta = atof(argv[1]);
|
||||
if (Delta <= 1.0) JSCerror("Provide Delta > 1.");
|
||||
int N = atoi(argv[2]);
|
||||
if (N % 2) JSCerror("Provide an even Delta.");
|
||||
int M = N/2;
|
||||
|
||||
// Define the chain: J, Delta, h, Nsites
|
||||
Heis_Chain chain(1.0, Delta, 0.0, N);
|
||||
|
||||
Heis_Base gbase(chain, M);
|
||||
|
||||
XXZ_gpd_Bethe_State gstate(chain, gbase);
|
||||
gstate.Compute_All(true);
|
||||
|
||||
XXZ_gpd_Bethe_State estate(chain, gbase);
|
||||
estate.Ix2[0][0] = M+1; // umklapp excitation
|
||||
estate.Compute_All(true);
|
||||
|
||||
stringstream basestrstream;
|
||||
basestrstream << M-2 << "x1";
|
||||
string basestr = basestrstream.str();
|
||||
Heis_Base basegap(chain, basestr);
|
||||
XXZ_gpd_Bethe_State estategap(chain, basegap);
|
||||
estategap.Compute_All(true);
|
||||
|
||||
if (!gstate.conv) JSCerror("Ground state did not converge.");
|
||||
if (!estate.conv) JSCerror("Umklapp state did not converge.");
|
||||
if (!estategap.conv) JSCerror("Gap state did not converge.");
|
||||
|
||||
cout << Delta << "\t" << N << "\t" << setprecision(12) << exp(real(ln_Sz_ME (gstate, estate)))/sqrt(N) << "\t" << estategap.E - gstate.E << endl;
|
||||
|
||||
}
|
||||
|
||||
else if (argc == 5) { // Do a scan in Delta
|
||||
|
||||
int N = atoi(argv[1]);
|
||||
if (N % 2) JSCerror("Provide an even Delta.");
|
||||
int M = N/2;
|
||||
|
||||
DP Deltamin = atof(argv[2]);
|
||||
if (Deltamin <= 1.0) JSCerror("Provide Deltamin > 1.");
|
||||
|
||||
DP Deltamax = atof(argv[3]);
|
||||
if (Deltamin <= 1.0) JSCerror("Provide Deltamax > Deltamin.");
|
||||
|
||||
int NDelta = atoi(argv[4]);
|
||||
|
||||
for (int iDelta = 0; iDelta <= NDelta; ++iDelta) {
|
||||
|
||||
DP Delta = (Deltamin * (NDelta -iDelta) + Deltamax * iDelta)/NDelta;
|
||||
|
||||
// Define the chain: J, Delta, h, Nsites
|
||||
Heis_Chain chain(1.0, Delta, 0.0, N);
|
||||
|
||||
Heis_Base gbase(chain, M);
|
||||
|
||||
XXZ_gpd_Bethe_State gstate(chain, gbase);
|
||||
gstate.Compute_All(true);
|
||||
|
||||
XXZ_gpd_Bethe_State estate(chain, gbase);
|
||||
estate.Ix2[0][0] = M+1; // umklapp excitation
|
||||
estate.Compute_All(true);
|
||||
|
||||
stringstream basestrstream;
|
||||
basestrstream << M-2 << "x1";
|
||||
string basestr = basestrstream.str();
|
||||
Heis_Base basegap(chain, basestr);
|
||||
XXZ_gpd_Bethe_State estategap(chain, basegap);
|
||||
estategap.Compute_All(true);
|
||||
|
||||
if (!gstate.conv) JSCerror("Ground state did not converge.");
|
||||
if (!estate.conv) JSCerror("Umklapp state did not converge.");
|
||||
if (!estategap.conv) JSCerror("Gap state did not converge.");
|
||||
|
||||
cout << Delta << "\t" << N << "\t" << setprecision(12) << exp(real(ln_Sz_ME (gstate, estate)))/sqrt(N) << "\t" << estategap.E - gstate.E << endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c) 2007.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: mrqmin.cc
|
||||
|
||||
Purpose: Nonlinear fitting
|
||||
|
||||
Last modified: 14/08/07
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
void covsrt (SQMat_DP& covar, Vect<bool>& ia, const int mfit)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
int ma = ia.size();
|
||||
|
||||
for (i = mfit; i < ma; i++)
|
||||
for (j = 0; j < i+1; j++) covar[i][j] = covar[j][i] = 0.0;
|
||||
k = mfit - 1;
|
||||
for (j = ma - 1; j >= 0; j--) {
|
||||
if (ia[j]) {
|
||||
for (i = 0; i < ma; i++) SWAP(covar[i][k], covar[i][j]);
|
||||
for (i = 0; i < ma; i++) SWAP(covar[k][i], covar[j][i]);
|
||||
k--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c) 2006.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: lin_reg.cc
|
||||
|
||||
Purpose: Linear regression
|
||||
|
||||
Last modified: 11/05/07
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
void lin_reg (Vect_DP x, Vect_DP y, Vect_DP sigma, DP& a, DP& b, DP& chisq)
|
||||
{
|
||||
// Performs simple linear regression on data
|
||||
|
||||
int Npts = x.size();
|
||||
|
||||
DP S = 0.0;
|
||||
DP Sx = 0.0;
|
||||
DP Sy = 0.0;
|
||||
DP Stt = 0.0;
|
||||
Vect_DP t(0.0, Npts);
|
||||
|
||||
for (int i = 0; i < Npts; ++i) {
|
||||
S += 1.0/(sigma[i] * sigma[i]);
|
||||
Sx += x[i]/(sigma[i] * sigma[i]);
|
||||
Sy += y[i]/(sigma[i] * sigma[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < Npts; ++i) {
|
||||
t[i] = (x[i] - Sx/S)/sigma[i];
|
||||
Stt += t[i] * t[i];
|
||||
}
|
||||
|
||||
a = 0.0;
|
||||
b = 0.0;
|
||||
for (int i = 0; i < Npts; ++i) {
|
||||
b += t[i] * y[i]/sigma[i];
|
||||
}
|
||||
b /= Stt;
|
||||
a = (Sy - Sx * b)/S;
|
||||
|
||||
chisq = 0.0;
|
||||
for (int i = 0; i < Npts; ++i) {
|
||||
chisq += (y[i] - a - b * x[i]) * (y[i] - a - b * x[i]) / (sigma[i] * sigma[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void lin_reg (Vect_DP x, Vect_DP y, DP& a, DP& b, DP& chisq)
|
||||
{
|
||||
// Assumes all sigma == 1
|
||||
|
||||
Vect_DP sigma(1.0, x.size());
|
||||
|
||||
lin_reg (x, y, sigma, a, b, chisq);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's C++ library.
|
||||
|
||||
Copyright (c) 2007.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: mrqmin.cc
|
||||
|
||||
Purpose: Nonlinear fitting
|
||||
|
||||
Last modified: 14/08/07
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
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)
|
||||
{
|
||||
// Levenberg-Marquardt method. See NRC++ p.691.
|
||||
|
||||
static int mfit;
|
||||
static DP ochisq;
|
||||
int j, k, l;
|
||||
|
||||
int ma = a.size();
|
||||
static SQMat_DP oneda (ma);
|
||||
static Vect_DP atry(ma);
|
||||
static Vect_DP beta(ma);
|
||||
static Vect_DP da(ma);
|
||||
|
||||
if (alambda < 0.0) {
|
||||
mfit = 0;
|
||||
for (j = 0; j < ma; j++)
|
||||
if (ia[j]) mfit++;
|
||||
alambda = 0.001;
|
||||
mrqcof (x, y, sig, a, ia, alpha, beta, chisq, funcs);
|
||||
ochisq = chisq;
|
||||
for (j = 0; j < ma; j++) atry[j] = a[j];
|
||||
}
|
||||
|
||||
SQMat_DP temp (mfit);
|
||||
|
||||
for (j = 0; j < mfit; j++) {
|
||||
for (k = 0; k < mfit; k++) covar[j][k] = alpha[j][k];
|
||||
covar[j][j] = alpha[j][j] * (1.0 + alambda);
|
||||
for (k = 0; k < mfit; k++) temp[j][k] = covar[j][k];
|
||||
oneda[j][0] = beta[j];
|
||||
}
|
||||
|
||||
gaussj (temp, oneda);
|
||||
for (j = 0; j < mfit; j++) {
|
||||
for (k = 0; k < mfit; k++) covar[j][k] = temp[j][k];
|
||||
da[j] = oneda[j][0];
|
||||
}
|
||||
|
||||
if (alambda == 0.0) {
|
||||
covsrt (covar, ia, mfit);
|
||||
covsrt (alpha, ia, mfit);
|
||||
return;
|
||||
}
|
||||
|
||||
for (j = 0, l = 0; l < ma; l++)
|
||||
if (ia[l]) atry[l] = a[l] + da[j++];
|
||||
|
||||
mrqcof (x, y, sig, atry, ia, covar, da, chisq, funcs);
|
||||
|
||||
if (chisq < ochisq) {
|
||||
alambda *= 0.1;
|
||||
ochisq = chisq;
|
||||
for (j = 0; j < mfit; j++) {
|
||||
for (k = 0; k < mfit; k++) alpha[j][k] = covar[j][k];
|
||||
beta[j] = da[j];
|
||||
}
|
||||
for (l = 0; l < ma; l++) a[l] = atry[l];
|
||||
} else {
|
||||
alambda *= 10.0;
|
||||
chisq = ochisq;
|
||||
}
|
||||
}
|
||||
|
||||
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&))
|
||||
{
|
||||
int i, j, k, l, m, mfit = 0;
|
||||
DP ymod, wt, sig2i, dy;
|
||||
|
||||
int ndata = x.size();
|
||||
int ma = a.size();
|
||||
|
||||
Vect_DP dyda (ma);
|
||||
|
||||
for (j = 0; j < ma; j++)
|
||||
if (ia[j]) mfit++;
|
||||
for (j = 0; j < mfit; j++) {
|
||||
for (k = 0; k <= j; k++) alpha[j][k] = 0.0;
|
||||
beta[j] = 0.0;
|
||||
}
|
||||
|
||||
chisq = 0.0;
|
||||
for (i = 0; i < ndata; i++) {
|
||||
funcs (x[i], a, ymod, dyda);
|
||||
sig2i = 1.0/(sig[i] * sig[i]);
|
||||
dy = y[i] - ymod;
|
||||
for (j = 0, l = 0; l < ma; l++) {
|
||||
if (ia[l]) {
|
||||
wt = dyda[l] * sig2i;
|
||||
for (k = 0, m = 0; m < l+1; m++)
|
||||
if (ia[m]) alpha[j][k++] += wt * dyda[m];
|
||||
beta[j++] += dy * wt;
|
||||
}
|
||||
}
|
||||
chisq += dy * dy * sig2i;
|
||||
}
|
||||
for (j = 1; j < mfit; j++)
|
||||
for (k = 0; k < j; k++) alpha[k][j] = alpha[j][k];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#include "JSC.h"
|
||||
using namespace std;
|
||||
|
||||
void JSC::polint(Vect_DP& xa, Vect_DP& ya, const DP x, DP& y, DP& dy)
|
||||
{
|
||||
// Polynomial interpolation/extrapolation, NR page 113.
|
||||
|
||||
int i, m, ns=0;
|
||||
DP den, dif, dift, ho, hp, w;
|
||||
|
||||
int n = xa.size();
|
||||
Vect_DP c(n), d(n);
|
||||
dif = fabs(x-xa[0]);
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((dift = fabs(x-xa[i])) < dif) {
|
||||
ns = i;
|
||||
dif = dift;
|
||||
}
|
||||
c[i] = ya[i];
|
||||
d[i] = ya[i];
|
||||
}
|
||||
y = ya[ns--];
|
||||
for (m = 1; m < n; m++) {
|
||||
for (i = 0; i < n-m; i++) {
|
||||
ho = xa[i] - x;
|
||||
hp = xa[i+m] - x;
|
||||
w = c[i+1] - d[i];
|
||||
if ((den = ho-hp) == 0.0) JSCerror("Error in routine polint.");
|
||||
den = w/den;
|
||||
d[i] = hp * den;
|
||||
c[i] = ho * den;
|
||||
}
|
||||
y += (dy = (2 * (ns + 1) < (n-m) ? c[ns + 1] : d[ns--]));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#include "JSC.h"
|
||||
using namespace std;
|
||||
|
||||
void JSC::polint(Vect_CX& xa, Vect_CX& ya, const complex<DP> x, complex<DP>& y, complex<DP>& dy)
|
||||
{
|
||||
// Polynomial interpolation/extrapolation, NR page 113.
|
||||
|
||||
int i, m, ns=0;
|
||||
DP dif, dift;
|
||||
complex<DP> den, ho, hp, w;
|
||||
|
||||
int n = xa.size();
|
||||
Vect_CX c(n), d(n);
|
||||
dif = abs(x-xa[0]);
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((dift = abs(x-xa[i])) < dif) {
|
||||
ns = i;
|
||||
dif = dift;
|
||||
}
|
||||
c[i] = ya[i];
|
||||
d[i] = ya[i];
|
||||
}
|
||||
y = ya[ns--];
|
||||
for (m = 1; m < n; m++) {
|
||||
for (i = 0; i < n-m; i++) {
|
||||
ho = xa[i] - x;
|
||||
hp = xa[i+m] - x;
|
||||
w = c[i+1] - d[i];
|
||||
if ((den = ho-hp) == 0.0) JSCerror("Error in routine polint_cx.");
|
||||
den = w/den;
|
||||
d[i] = hp * den;
|
||||
c[i] = ho * den;
|
||||
}
|
||||
y += (dy = (2 * (ns + 1) < (n-m) ? c[ns + 1] : d[ns--]));
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,142 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/Heis_Chem_Pot.cc
|
||||
|
||||
Purpose: calculates the chemical potential.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
DP Ezero (DP Delta, int N, int M)
|
||||
{
|
||||
// Returns the energy of the ground state with M down spins
|
||||
|
||||
if (M < 0 || M > N/2) JSCerror("M out of bounds in Ezero.");
|
||||
|
||||
DP E = -1.0; // sentinel value
|
||||
|
||||
if (M == 0) E = N * Delta/4.0;
|
||||
|
||||
else {
|
||||
|
||||
Heis_Chain BD1(1.0, Delta, 0.0, N);
|
||||
|
||||
Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
|
||||
|
||||
Nrapidities_groundstate[0] = M;
|
||||
|
||||
Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
|
||||
|
||||
if ((Delta > 0.0) && (Delta < 1.0)) {
|
||||
XXZ_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else if (Delta == 1.0) {
|
||||
XXX_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else if (Delta > 1.0) {
|
||||
XXZ_gpd_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else JSCerror("Anisotropy out of bounds in Ezero.");
|
||||
}
|
||||
|
||||
return(E);
|
||||
}
|
||||
|
||||
DP H_vs_M (DP Delta, int N, int M)
|
||||
{
|
||||
// Assumes dE/dM = 0 = dE_0/dM + h, with dE_0/dM = E_0(M) - E_0 (M - 1)
|
||||
|
||||
DP H = 0.0;
|
||||
|
||||
if (2*M == N) H = 0.0;
|
||||
|
||||
else if (Delta <= 1.0) H = Ezero (Delta, N, M - 1) - Ezero (Delta, N, M);
|
||||
|
||||
return(H);
|
||||
}
|
||||
|
||||
DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref)
|
||||
{
|
||||
if (M < 0 || M > N/2 - 1) {
|
||||
cout << "M = " << M << endl;
|
||||
JSCerror("M out of bounds in HZmin.");
|
||||
}
|
||||
|
||||
if (Ezero_ref[M] == -1.0) Ezero_ref[M] = Ezero(Delta, N, M);
|
||||
if (Ezero_ref[M + 1] == -1.0) Ezero_ref[M + 1] = Ezero(Delta, N, M + 1);
|
||||
|
||||
return(Ezero_ref[M] - Ezero_ref[M + 1]);
|
||||
}
|
||||
|
||||
int M_vs_H (DP Delta, int N, DP HZ)
|
||||
{
|
||||
// Returns the value of M for given field HZ
|
||||
|
||||
if (HZ < 0.0) JSCerror("Please use a positive field in M_vs_H.");
|
||||
|
||||
else if (HZ == 0.0) return(N/2);
|
||||
|
||||
// Here, -1.0 is a sentinel value.
|
||||
Vect_DP Ezero(-1.0, N/2 + 1); // contains the GSE[M].
|
||||
|
||||
// We look for M s.t. HZmin[M] < HZ <= HZmin[M + 1]
|
||||
|
||||
int M_actual = N/4; // start somewhere in middle
|
||||
int M_step = N/8 - 1; // step
|
||||
DP HZmin_actual = 0.0;
|
||||
DP HZmax_actual = 0.0;
|
||||
bool M_found = false;
|
||||
|
||||
if (HZ >= 1.0 + Delta) M_actual = 0; // saturation
|
||||
|
||||
else {
|
||||
|
||||
HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
|
||||
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
|
||||
|
||||
while (!M_found) {
|
||||
|
||||
if (HZmin_actual > HZ) M_actual += M_step;
|
||||
else if (HZmax_actual <= HZ) M_actual -= M_step;
|
||||
|
||||
M_step = (M_step + 1)/2;
|
||||
|
||||
HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
|
||||
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
|
||||
|
||||
M_found = (HZmin_actual < HZ && HZ <= HZmax_actual);
|
||||
|
||||
//cout << "M_actual = " << M_actual << "\tM_step = " << M_step
|
||||
// << "\tHZmin_actual = " << HZmin_actual << "\tHZmax_actual = " << HZmax_actual << "\tHZ = " << HZ << "\t" << M_found << endl;
|
||||
}
|
||||
}
|
||||
//cout << "M found = " << M_actual << "\tHZmax = " << Ezero[M_actual] - Ezero[M_actual + 1] << "\tHZmin = " << Ezero[M_actual - 1] - Ezero[M_actual] << endl;
|
||||
|
||||
return(M_actual);
|
||||
}
|
||||
|
||||
DP Chemical_Potential (const Heis_Bethe_State& AveragingState)
|
||||
{
|
||||
return(-H_vs_M (AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown)); // - sign since E_{M+1} - E_M = -H
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,376 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/Heis_Matrix_Element_Contrib.cc
|
||||
|
||||
Purpose: handles the generic call for a matrix element.
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXZ_Bethe_State& LeftState,
|
||||
//XXZ_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState,
|
||||
// XXZ_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState,
|
||||
XXZ_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
|
||||
{
|
||||
// This function prints the matrix information to the fstream,
|
||||
// and returns a weighed `data_value' to be multiplied by sumrule_factor,
|
||||
// to determine if scanning along this thread should be continued.
|
||||
|
||||
// Identify which matrix element is needed from the number of particles in Left and Right states:
|
||||
|
||||
bool fixed_iK = (iKmin == iKmax);
|
||||
|
||||
DP ME = 0.0;
|
||||
if (!(LeftState.conv && RightState.conv)) ME = 0.0;
|
||||
|
||||
else if (whichDSF == 'Z')
|
||||
ME = LeftState.E - RightState.E;
|
||||
else if (whichDSF == 'm')
|
||||
ME = exp(real(ln_Smin_ME (RightState, LeftState)));
|
||||
else if (whichDSF == 'z') {
|
||||
if (LeftState.label == RightState.label)
|
||||
//MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
|
||||
ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
|
||||
else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
|
||||
}
|
||||
else if (whichDSF == 'p')
|
||||
ME = exp(real(ln_Smin_ME (LeftState, RightState)));
|
||||
else JSCerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
|
||||
|
||||
if (is_nan(ME)) ME = 0.0;
|
||||
|
||||
//if (LeftState.dev > 1.0e-16 || RightState.dev > 1.0e-16) ME = 0.0; // kill deviated contributions
|
||||
|
||||
// Do the momentum business:
|
||||
int iKout = LeftState.iK - RightState.iK;
|
||||
while(iKout < 0) iKout += RightState.chain.Nsites;
|
||||
while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
|
||||
|
||||
// Print information to fstream:
|
||||
if (iKout >= iKmin && iKout <= iKmax) {
|
||||
if (whichDSF == 'Z') {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
else {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
} // if iKmin <= iKout <= iKmax
|
||||
|
||||
// Calculate and return the data_value:
|
||||
DP data_value = ME * ME;
|
||||
//DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
|
||||
|
||||
if (whichDSF == 'Z') // use 1/(1 + omega)
|
||||
data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
else if (fixed_iK) // data value is MEsq * omega:
|
||||
data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
|
||||
return(data_value);
|
||||
}
|
||||
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXX_Bethe_State& LeftState,
|
||||
//XXX_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState,
|
||||
//XXX_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState,
|
||||
XXX_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
|
||||
{
|
||||
// This function prints the matrix element information to the fstream,
|
||||
// and returns a weighed `data_value' to be multiplied by sumrule_factor,
|
||||
// to determine if scanning along this thread should be continued.
|
||||
|
||||
// Identify which matrix element is needed from the number of particles in Left and Right states:
|
||||
|
||||
bool fixed_iK = (iKmin == iKmax);
|
||||
|
||||
DP ME = 0.0;
|
||||
complex<DP> ME_CX = 0.0;
|
||||
|
||||
int nrinfrap = 0; // for energy shift from chemical potential
|
||||
|
||||
if (!(LeftState.conv && RightState.conv)) { ME = 0.0; ME_CX = 0.0;}
|
||||
|
||||
else if (whichDSF == 'Z')
|
||||
ME = LeftState.E - RightState.E;
|
||||
else if (whichDSF == 'm')
|
||||
ME = exp(real(ln_Smin_ME (RightState, LeftState)));
|
||||
else if (whichDSF == 'z') {
|
||||
// Recognize the presence of an infinite rapidity:
|
||||
if (LeftState.base.Mdown == RightState.base.Mdown - 1) { // infinite rapidity present, use rescaled S^- matrix element instead of S^z one:
|
||||
nrinfrap = 1;
|
||||
// Correction factor for MEsq: Smffsq to Szffsq = 1/(N - 2M + 2)
|
||||
ME = sqrt(1.0/(RightState.chain.Nsites - 2*RightState.base.Mdown + 2)) * exp(real(ln_Smin_ME (RightState, LeftState)));
|
||||
}
|
||||
else { // no infinite rapidity, use S^z matrix element:
|
||||
if (LeftState.label == RightState.label)
|
||||
//MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
|
||||
ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
|
||||
else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
|
||||
}
|
||||
}
|
||||
else if (whichDSF == 'p') {
|
||||
// Recognize the presence of two infinite rapidities:
|
||||
if (LeftState.base.Mdown == RightState.base.Mdown - 1) { // two infinite rapidities, use rescaled S^- matrix element instead of S^+
|
||||
nrinfrap = 2;
|
||||
// Correction factor for MEsq: Smffsq to Spffsq = 2/((N - 2M + 2) (N - 2M + 1))
|
||||
ME = sqrt(2.0/((RightState.chain.Nsites - 2*RightState.base.Mdown + 2.0) * (RightState.chain.Nsites - 2*RightState.base.Mdown + 1.0)))
|
||||
* exp(real(ln_Smin_ME (RightState, LeftState)));
|
||||
}
|
||||
else if (LeftState.base.Mdown == RightState.base.Mdown) { // one infinite rapidity, use rescaled S^z matrix element instead of S^+
|
||||
nrinfrap = 1;
|
||||
// Correction factor for MEsq: Szffsq to Spffsq = 4/(N - 2M)
|
||||
ME = sqrt(4.0/(RightState.chain.Nsites - 2* RightState.base.Mdown)) * exp(real(ln_Sz_ME (RightState, LeftState)));
|
||||
}
|
||||
else ME = exp(real(ln_Smin_ME (LeftState, RightState)));
|
||||
}
|
||||
else if (whichDSF == 'a') // S^z_j S^z_{j+1} operator
|
||||
ME = exp(real(ln_Szz_ME (LeftState, RightState)));
|
||||
else if (whichDSF == 'b') // S^z_j S^-_{j+1} + h.c. operator
|
||||
ME = exp(real(ln_Szm_p_Smz_ME (RightState, LeftState)));
|
||||
else if (whichDSF == 'c') // S^-_j S^-{j+1} operator
|
||||
ME = exp(real(ln_Smm_ME (RightState, LeftState)));
|
||||
else if (whichDSF == 'q') // Geometric quench
|
||||
//ME_CX = ln_Overlap (LeftState, RightState);
|
||||
ME_CX = ln_Overlap (RightState, LeftState);
|
||||
else JSCerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
|
||||
|
||||
if (is_nan(ME)) ME = 0.0;
|
||||
if (is_nan(norm(ME_CX))) ME_CX = -100.0;
|
||||
|
||||
//if (LeftState.dev > 1.0e-16 || RightState.dev > 1.0e-16) {
|
||||
//ME = 0.0; ME_CX = (0.0,0.0); // kill deviated contributions
|
||||
//}
|
||||
|
||||
// Do the momentum business:
|
||||
int iKout = LeftState.iK - RightState.iK;
|
||||
while(iKout < 0) iKout += RightState.chain.Nsites;
|
||||
while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
|
||||
|
||||
// Print information to fstream:
|
||||
if (iKout >= iKmin && iKout <= iKmax) {
|
||||
if (whichDSF == 'Z') {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
else if (whichDSF == 'q') {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
<< real(ME_CX) << "\t" << imag(ME_CX) - twoPI * int(imag(ME_CX)/twoPI + 1.0e-10) << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
|
||||
else {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
} // if iKmin <= iKout <= iKmax
|
||||
|
||||
// Calculate and return the data_value:
|
||||
DP data_value = ME * ME;
|
||||
//DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
|
||||
if (whichDSF == 'Z') // use 1/(1 + omega)
|
||||
data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
else if (whichDSF == 'q')
|
||||
data_value = exp(2.0 * real(ME_CX));
|
||||
else if (fixed_iK) // data value is MEsq * omega:
|
||||
data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
|
||||
return(data_value);
|
||||
}
|
||||
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXZ_gpd_Bethe_State& LeftState,
|
||||
//XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState,
|
||||
// XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
|
||||
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState,
|
||||
XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
|
||||
{
|
||||
// This function prints the matrix element information to the fstream,
|
||||
// and returns a weighed `data_value' to be multiplied by sumrule_factor,
|
||||
// to determine if scanning along this thread should be continued.
|
||||
|
||||
/*
|
||||
cout << "\t" << LeftState.label << endl << "\t" << LeftState.Ix2 << endl;
|
||||
cout << "\t0: ";
|
||||
for (int i = 0; i < LeftState.base.Nrap[0]; ++i) cout << LeftState.lambda[0][i]*2.0/PI << "\t";
|
||||
cout << endl;
|
||||
cout << "\t1: ";
|
||||
for (int i = 0; i < LeftState.base.Nrap[1]; ++i) cout << LeftState.lambda[1][i]*2.0/PI << "\t";
|
||||
cout << endl;
|
||||
*/
|
||||
|
||||
bool fixed_iK = (iKmin == iKmax);
|
||||
|
||||
|
||||
// If any of the rapidities outside of fundamental interval -pi/2 < lambda <= pi/2, set matrix element to zero.
|
||||
bool rap_in_fundamental = true;
|
||||
int sum1 = 0;
|
||||
for (int j = 0; j < LeftState.chain.Nstrings; ++j) {
|
||||
//for (int alpha = 0; alpha < LeftState.base.Nrap[j]; ++alpha) {
|
||||
//if (LeftState.lambda[j][alpha] <= -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
|
||||
//if (LeftState.lambda[j][alpha] <= -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
|
||||
//rap_in_fundamental = false;
|
||||
//}
|
||||
|
||||
/*
|
||||
// TEST 2014 06 26: comment this out, replace by -\pi/2 \leq \lambda \leq \pi/2, see below
|
||||
if (LeftState.base.Nrap[j] > 0 && LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
|
||||
rap_in_fundamental = false;
|
||||
|
||||
sum1 = 0;
|
||||
for (int k = 0; k < LeftState.chain.Nstrings; ++k)
|
||||
sum1 += LeftState.base.Nrap[k] * (2 * JSC::min(LeftState.chain.Str_L[j], LeftState.chain.Str_L[k]) - ((j == k) ? 1 : 0));
|
||||
// This almost does it: only missing are the states with one on -PI/2 and one on PI/2
|
||||
if (LeftState.base.Nrap[j] >= 1
|
||||
&& (LeftState.Ix2[j][0] <= -(LeftState.chain.Nsites - sum1)
|
||||
|| (LeftState.Ix2[j][LeftState.base.Nrap[j] - 1] - LeftState.Ix2[j][0])
|
||||
> 2*(LeftState.chain.Nsites - sum1)))
|
||||
rap_in_fundamental = false;
|
||||
*/
|
||||
|
||||
// attempt 2014 06 26
|
||||
//for (int alpha = 0; alpha < LeftState.base.Nrap[j]; ++alpha) {
|
||||
//if (LeftState.lambda[j][alpha] < -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
|
||||
// rap_in_fundamental = false;
|
||||
//}
|
||||
/*
|
||||
if (LeftState.base.Nrap[j] > 0 &&
|
||||
((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
|
||||
|| LeftState.lambda[j][0] < -0.5*PI + 1.0e-10
|
||||
|| LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > 0.5*PI
|
||||
//|| LeftState.lambda[j][0] > 0.5*PI
|
||||
//((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI - 1.0e-10)
|
||||
//|| LeftState.lambda[j][0] < -0.5*PI + 1.0e-10
|
||||
//|| LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > 0.5*PI + 1.0e-10
|
||||
)) // include safety in limits
|
||||
rap_in_fundamental = false;
|
||||
*/
|
||||
/*
|
||||
if (LeftState.base.Nrap[j] > 0 &&
|
||||
((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
|
||||
//|| (LeftState.base.Nrap[j] == 1 && fabs(LeftState.lambda[j][0]) > 0.5*PI)
|
||||
))
|
||||
rap_in_fundamental = false;
|
||||
*/
|
||||
|
||||
// Logic: allow rapidities -PI/2 <= lambda <= PI/2 (including boundaries)
|
||||
if (LeftState.base.Nrap[j] > 0 &&
|
||||
(LeftState.lambda[j][0] < -PI/2 || LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > PI/2))
|
||||
rap_in_fundamental = false;
|
||||
if (RightState.base.Nrap[j] > 0 &&
|
||||
(RightState.lambda[j][0] < -PI/2 || RightState.lambda[j][RightState.base.Nrap[j] - 1] > PI/2))
|
||||
rap_in_fundamental = false;
|
||||
|
||||
// rapidities should also be ordered as the quantum numbers:
|
||||
for (int alpha = 1; alpha < LeftState.base.Nrap[j]; ++alpha)
|
||||
if (LeftState.lambda[j][alpha - 1] >= LeftState.lambda[j][alpha])
|
||||
rap_in_fundamental = false;
|
||||
for (int alpha = 1; alpha < RightState.base.Nrap[j]; ++alpha)
|
||||
if (RightState.lambda[j][alpha - 1] >= RightState.lambda[j][alpha])
|
||||
rap_in_fundamental = false;
|
||||
|
||||
} // for int j
|
||||
|
||||
|
||||
// Identify which matrix element is needed from the number of particles in Left and Right states:
|
||||
DP ME = 0.0;
|
||||
//if (!(LeftState.conv && RightState.conv)) ME = 0.0;
|
||||
if (!(LeftState.conv && RightState.conv && rap_in_fundamental)) ME = 0.0;
|
||||
|
||||
else if (whichDSF == 'Z')
|
||||
ME = LeftState.E - RightState.E;
|
||||
else if (whichDSF == 'm')
|
||||
ME = exp(real(ln_Smin_ME (RightState, LeftState)));
|
||||
else if (whichDSF == 'z') {
|
||||
if (LeftState.label == RightState.label)
|
||||
//MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
|
||||
ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
|
||||
else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
|
||||
}
|
||||
else if (whichDSF == 'p')
|
||||
ME = exp(real(ln_Smin_ME (LeftState, RightState)));
|
||||
else JSCerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
|
||||
|
||||
if (is_nan(ME)) ME = 0.0;
|
||||
|
||||
//if (LeftState.dev > 1.0e+2 || RightState.dev > 1.0e+2) ME = 0.0; // kill deviated contributions
|
||||
if (fabs(ME) > 1.0) ME = 0.0;
|
||||
|
||||
// Do the momentum business:
|
||||
int iKout = LeftState.iK - RightState.iK;
|
||||
while(iKout < 0) iKout += RightState.chain.Nsites;
|
||||
while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
|
||||
|
||||
// Print information to fstream:
|
||||
if (iKout >= iKmin && iKout <= iKmax) {
|
||||
if (whichDSF == 'Z') {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
}
|
||||
else {
|
||||
DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t"
|
||||
<< iKout << "\t"
|
||||
<< ME << "\t"
|
||||
//<< LeftState.conv << "\t"
|
||||
<< setprecision(3) << LeftState.dev << "\t"
|
||||
<< LeftState.label;
|
||||
|
||||
/*
|
||||
cout << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" << iKout << "\t" << ME << "\t" << setprecision(3) << LeftState.dev << "\t" << LeftState.label << "\t" << setprecision(16) << LeftState.lambda[0][0]/PI << "\t" << LeftState.Ix2[0][0] << "\t" << LeftState.lambda[0][LeftState.base.Nrap[0] - 1]/PI << "\t" << LeftState.Ix2[0][LeftState.base.Nrap[0] - 1];
|
||||
if (LeftState.base.Nrap[1] > 0) cout << "\t" << LeftState.lambda[1][0]/PI << "\t" << LeftState.Ix2[1][0];
|
||||
if (LeftState.lambda[0][0] < -0.5*PI + 1.0e-10 || LeftState.lambda[0][LeftState.base.Nrap[0] - 1] > 0.5*PI - 1.0e-10 || (LeftState.base.Nrap[1] > 0 && (LeftState.lambda[1][0] < -0.5*PI || LeftState.lambda[1][0] > 0.5*PI))) cout << "\t" << "*****";
|
||||
cout << endl;
|
||||
*/
|
||||
|
||||
}
|
||||
} // if iKmin <= iKout <= iKmax
|
||||
|
||||
// Calculate and return the data_value:
|
||||
DP data_value = ME * ME;
|
||||
//DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
|
||||
if (whichDSF == 'Z') // use 1/(1 + omega)
|
||||
data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
else if (fixed_iK) // data value is MEsq * omega:
|
||||
data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
|
||||
|
||||
return(data_value);
|
||||
}
|
||||
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,255 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/Heis_Sumrules.cc
|
||||
|
||||
Purpose: defines sumrule factors for Heisenberg
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
DP X_avg (char xyorz, DP Delta, int N, int M)
|
||||
{
|
||||
// Calculates \sum_j < S_j^a S_{j+1}^a >, a = x, y or z.
|
||||
|
||||
DP eps_Delta = 0.00000001;
|
||||
|
||||
if (Delta < 1.0 && 1.0 - Delta < 1.0e-6) eps_Delta *= -1.0;
|
||||
|
||||
// Define the chain: J, Delta, h, Nsites
|
||||
Heis_Chain chain(1.0, Delta, 0.0, N);
|
||||
|
||||
// Define the base: chain, Mdown
|
||||
Heis_Base gbase(chain, M);
|
||||
|
||||
// Define the chain: J, Delta, h, Nsites
|
||||
Heis_Chain chain2(1.0, Delta + eps_Delta, 0.0, N);
|
||||
|
||||
// Define the base: chain, Mdown
|
||||
Heis_Base gbase2(chain2, M);
|
||||
|
||||
DP E0_Delta = 0.0;
|
||||
DP E0_Delta_eps = 0.0;
|
||||
|
||||
if (Delta > 0.0 && Delta < 1.0) {
|
||||
|
||||
// Define the ground state
|
||||
XXZ_Bethe_State gstate(chain, gbase);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate.Compute_All(true);
|
||||
|
||||
E0_Delta = gstate.E;
|
||||
|
||||
// Define the ground state
|
||||
XXZ_Bethe_State gstate2(chain2, gbase2);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate2.Compute_All(true);
|
||||
|
||||
E0_Delta_eps = gstate2.E;
|
||||
}
|
||||
|
||||
else if (Delta == 1.0) {
|
||||
// Define the ground state
|
||||
XXX_Bethe_State gstate(chain, gbase);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate.Compute_All(true);
|
||||
|
||||
E0_Delta = gstate.E;
|
||||
|
||||
// Define the ground state
|
||||
XXZ_gpd_Bethe_State gstate2(chain2, gbase2); // need XXZ_gpd here
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate2.Compute_All(true);
|
||||
|
||||
E0_Delta_eps = gstate2.E;
|
||||
}
|
||||
|
||||
else if (Delta > 1.0) {
|
||||
// Define the ground state
|
||||
XXZ_gpd_Bethe_State gstate(chain, gbase);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate.Compute_All(true);
|
||||
|
||||
E0_Delta = gstate.E;
|
||||
|
||||
// Define the ground state
|
||||
XXZ_gpd_Bethe_State gstate2(chain2, gbase2);
|
||||
|
||||
// Compute everything about the ground state
|
||||
gstate2.Compute_All(true);
|
||||
|
||||
E0_Delta_eps = gstate2.E;
|
||||
}
|
||||
|
||||
else JSCerror("Wrong anisotropy in S1_sumrule_factor.");
|
||||
|
||||
DP answer = 0.0;
|
||||
//if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
|
||||
if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
|
||||
|
||||
// Careful for z ! Hamiltonian defined as S^z S^z - 1/4, so add back N/4:
|
||||
else if (xyorz == 'z') answer = (E0_Delta_eps - E0_Delta)/eps_Delta + 0.25 * N;
|
||||
|
||||
else JSCerror("option not implemented in X_avg.");
|
||||
|
||||
return(answer);
|
||||
}
|
||||
|
||||
DP S1_sumrule_factor (char mporz, DP Delta, int N, int M, DP Chem_Pot, int iK)
|
||||
{
|
||||
|
||||
DP X_x = X_avg ('x', Delta, N, M);
|
||||
DP X_z = X_avg ('z', Delta, N, M);
|
||||
|
||||
DP sumrule = 0.0;
|
||||
|
||||
if (mporz == 'm' || mporz == 'p') sumrule = - 4.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z + 0.5 * Chem_Pot * 0.5 *(N - 2*M))/N;
|
||||
//if (mporz == 'm' || mporz == 'p') sumrule = - 1.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * 2.0 * X_x + (Delta - cos((twoPI * iK)/N)) * (X_x + X_z))/N;
|
||||
|
||||
else if (mporz == 'z') sumrule = iK == 0 ? 1.0 : -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
|
||||
|
||||
else if (mporz == 'Z') sumrule = 1.0; // partition function
|
||||
else if (mporz == 'a') sumrule = 1.0;
|
||||
else if (mporz == 'b') sumrule = 1.0;
|
||||
else if (mporz == 'c') sumrule = 1.0;
|
||||
|
||||
else JSCerror("option not implemented in S1_sumrule_factor.");
|
||||
|
||||
//return(1.0/sumrule);
|
||||
return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N
|
||||
}
|
||||
|
||||
DP S1_sumrule_factor (char mporz, DP Delta, int N, int M, DP Chem_Pot, DP X_x, DP X_z, int iK)
|
||||
{
|
||||
|
||||
//DP X_x = X_avg ('x', Delta, N, M);
|
||||
//DP X_z = X_avg ('z', Delta, N, M);
|
||||
|
||||
DP sumrule = 0.0;
|
||||
|
||||
if (mporz == 'm' || mporz == 'p') sumrule = - 4.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * X_x + (Delta - cos((twoPI * iK)/N)) * X_z + 0.5 * Chem_Pot * 0.5 *(N - 2*M))/N;
|
||||
//if (mporz == 'm' || mporz == 'p') sumrule = - 1.0 * ((1.0 - Delta * cos((twoPI * iK)/N)) * 2.0 * X_x + (Delta - cos((twoPI * iK)/N)) * (X_x + X_z))/N;
|
||||
|
||||
else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
|
||||
|
||||
else if (mporz == 'Z') sumrule = 1.0; // partition function
|
||||
else if (mporz == 'a') sumrule = 1.0;
|
||||
else if (mporz == 'b') sumrule = 1.0;
|
||||
else if (mporz == 'c') sumrule = 1.0;
|
||||
|
||||
else JSCerror("option not implemented in S1_sumrule_factor.");
|
||||
|
||||
return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N
|
||||
}
|
||||
|
||||
|
||||
//DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& AveragingState, DP Chem_Pot, bool fixed_iK, int iKneeded)
|
||||
DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& AveragingState, DP Chem_Pot, int iKmin, int iKmax)
|
||||
{
|
||||
DP sumrule_factor = 1.0;
|
||||
//if (!fixed_iK) {
|
||||
if (iKmin != iKmax) {
|
||||
if (whichDSF == 'Z') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'm')
|
||||
sumrule_factor = 1.0/AveragingState.base.Mdown;
|
||||
else if (whichDSF == 'z') sumrule_factor = 1.0/(0.25 * AveragingState.chain.Nsites);
|
||||
else if (whichDSF == 'p') sumrule_factor = 1.0/(AveragingState.chain.Nsites - AveragingState.base.Mdown);
|
||||
else if (whichDSF == 'a') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'b') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'c') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
||||
|
||||
else JSCerror("whichDSF option not consistent in Sumrule_Factor");
|
||||
}
|
||||
//else if (fixed_iK) {
|
||||
else if (iKmin == iKmax) {
|
||||
if (whichDSF == 'Z') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'm' || whichDSF == 'z' || whichDSF == 'p')
|
||||
//sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, iKneeded);
|
||||
sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, Chem_Pot, iKmax);
|
||||
else if (whichDSF == 'a') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'b') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'c') sumrule_factor = 1.0;
|
||||
else if (whichDSF == 'q') sumrule_factor = 1.0;
|
||||
|
||||
else JSCerror("whichDSF option not consistent in Sumrule_Factor");
|
||||
}
|
||||
|
||||
|
||||
|
||||
return(sumrule_factor);
|
||||
}
|
||||
|
||||
|
||||
void Evaluate_F_Sumrule (string prefix, char whichDSF, const Heis_Bethe_State& AveragingState, DP Chem_Pot, int iKmin_ref, int iKmax_ref)
|
||||
{
|
||||
|
||||
stringstream RAW_stringstream; string RAW_string;
|
||||
RAW_stringstream << prefix << ".raw";
|
||||
RAW_string = RAW_stringstream.str(); const char* RAW_Cstr = RAW_string.c_str();
|
||||
|
||||
stringstream FSR_stringstream; string FSR_string;
|
||||
FSR_stringstream << prefix << ".fsr";
|
||||
FSR_string = FSR_stringstream.str(); const char* FSR_Cstr = FSR_string.c_str();
|
||||
|
||||
ifstream infile;
|
||||
infile.open(RAW_Cstr);
|
||||
if(infile.fail()) JSCerror("Could not open raw input file in Evaluate_F_Sumrule(Heis...).");
|
||||
|
||||
int iKmin = 0;
|
||||
int iKmax = AveragingState.chain.Nsites;
|
||||
int iKmod = AveragingState.chain.Nsites;
|
||||
|
||||
// We run through the data file to chech the f sumrule at each positive momenta:
|
||||
//Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);
|
||||
Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);
|
||||
|
||||
DP omega, ME;
|
||||
int iK, iKexc;
|
||||
//int conv;
|
||||
DP dev;
|
||||
string label;
|
||||
|
||||
while (infile.peek() != EOF) {
|
||||
infile >> omega >> iK >> ME >> dev >> label;
|
||||
//if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
|
||||
iKexc = iK;
|
||||
while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
|
||||
while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
|
||||
if (iKexc >= iKmin && iKexc <= iKmax) Sum_omega_MEsq[iKexc - iKmin] += omega * ME * ME;
|
||||
}
|
||||
|
||||
infile.close();
|
||||
|
||||
ofstream outfile;
|
||||
outfile.open(FSR_Cstr);
|
||||
outfile.precision(16);
|
||||
|
||||
DP X_x = X_avg ('x', AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown);
|
||||
DP X_z = X_avg ('z', AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown);
|
||||
|
||||
for (int i = iKmin; i <= iKmax; ++i) {
|
||||
if (i > iKmin) outfile << endl;
|
||||
outfile << i << "\t" << Sum_omega_MEsq[i] * S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, Chem_Pot, X_x, X_z, i);
|
||||
}
|
||||
|
||||
outfile.close();
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,139 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c) 2006-9.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: M_vs_H.cc
|
||||
|
||||
Purpose: field to and from magnetization for Heisenberg
|
||||
|
||||
Last modified: 21/10/09
|
||||
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
DP Ezero (DP Delta, int N, int M)
|
||||
{
|
||||
// Returns the energy of the ground state with M down spins
|
||||
|
||||
if (M < 0 || M > N/2) JSCerror("M out of bounds in Ezero.");
|
||||
|
||||
DP E = -1.0; // sentinel value
|
||||
|
||||
if (M == 0) E = N * Delta/4.0;
|
||||
|
||||
else {
|
||||
|
||||
Heis_Chain BD1(1.0, Delta, 0.0, N);
|
||||
|
||||
Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
|
||||
|
||||
Nrapidities_groundstate[0] = M;
|
||||
|
||||
Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
|
||||
|
||||
if ((Delta > 0.0) && (Delta < 1.0)) {
|
||||
XXZ_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else if (Delta == 1.0) {
|
||||
XXX_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else if (Delta > 1.0) {
|
||||
XXZ_gpd_Bethe_State groundstate(BD1, baseconfig_groundstate);
|
||||
groundstate.Compute_All(true);
|
||||
E = groundstate.E;
|
||||
}
|
||||
|
||||
else JSCerror("Anisotropy out of bounds in Ezero.");
|
||||
}
|
||||
|
||||
return(E);
|
||||
}
|
||||
|
||||
DP H_vs_M (DP Delta, int N, int M)
|
||||
{
|
||||
// Assumes dE/dM = 0 = dE_0/dM + h, with dE_0/dM = E_0(M) - E_0 (M - 1)
|
||||
|
||||
DP H = 0.0;
|
||||
|
||||
if (2*M == N) H = 0.0;
|
||||
|
||||
else if (Delta <= 1.0) H = Ezero (Delta, N, M - 1) - Ezero (Delta, N, M);
|
||||
|
||||
return(H);
|
||||
}
|
||||
|
||||
DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref)
|
||||
{
|
||||
if (M < 0 || M > N/2 - 1) {
|
||||
cout << "M = " << M << endl;
|
||||
JSCerror("M out of bounds in HZmin.");
|
||||
}
|
||||
|
||||
if (Ezero_ref[M] == -1.0) Ezero_ref[M] = Ezero(Delta, N, M);
|
||||
if (Ezero_ref[M + 1] == -1.0) Ezero_ref[M + 1] = Ezero(Delta, N, M + 1);
|
||||
|
||||
return(Ezero_ref[M] - Ezero_ref[M + 1]);
|
||||
}
|
||||
|
||||
int M_vs_H (DP Delta, int N, DP HZ)
|
||||
{
|
||||
// Returns the value of M for given field HZ
|
||||
|
||||
if (HZ < 0.0) JSCerror("Please use a positive field in M_vs_H.");
|
||||
|
||||
else if (HZ == 0.0) return(N/2);
|
||||
|
||||
// Here, -1.0 is a sentinel value.
|
||||
Vect_DP Ezero(-1.0, N/2 + 1); // contains the GSE[M].
|
||||
|
||||
// We look for M s.t. HZmin[M] < HZ <= HZmin[M + 1]
|
||||
|
||||
int M_actual = N/4; // start somewhere in middle
|
||||
int M_step = N/8 - 1; // step
|
||||
DP HZmin_actual = 0.0;
|
||||
DP HZmax_actual = 0.0;
|
||||
bool M_found = false;
|
||||
|
||||
if (HZ >= 1.0 + Delta) M_actual = 0; // saturation
|
||||
|
||||
else {
|
||||
|
||||
HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
|
||||
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
|
||||
|
||||
while (!M_found) {
|
||||
|
||||
if (HZmin_actual > HZ) M_actual += M_step;
|
||||
else if (HZmax_actual <= HZ) M_actual -= M_step;
|
||||
|
||||
M_step = (M_step + 1)/2;
|
||||
|
||||
HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
|
||||
HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
|
||||
|
||||
M_found = (HZmin_actual < HZ && HZ <= HZmax_actual);
|
||||
|
||||
//cout << "M_actual = " << M_actual << "\tM_step = " << M_step
|
||||
// << "\tHZmin_actual = " << HZmin_actual << "\tHZmax_actual = " << HZmax_actual << "\tHZ = " << HZ << "\t" << M_found << endl;
|
||||
}
|
||||
}
|
||||
//cout << "M found = " << M_actual << "\tHZmax = " << Ezero[M_actual] - Ezero[M_actual + 1] << "\tHZmin = " << Ezero[M_actual - 1] - Ezero[M_actual] << endl;
|
||||
|
||||
return(M_actual);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,626 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/XXX_Bethe_State.cc
|
||||
|
||||
Purpose: Defines all functions for XXX_Bethe_State
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// Function prototypes
|
||||
|
||||
DP Theta_XXX (DP lambda, int nj, int nk);
|
||||
DP ddlambda_Theta_XXX (DP lambda, int nj, int nk);
|
||||
|
||||
//***************************************************************************************************
|
||||
|
||||
// Function definitions: class XXX_Bethe_State
|
||||
|
||||
XXX_Bethe_State::XXX_Bethe_State ()
|
||||
: Heis_Bethe_State()
|
||||
{};
|
||||
|
||||
XXX_Bethe_State::XXX_Bethe_State (const XXX_Bethe_State& RefState) // copy constructor
|
||||
: Heis_Bethe_State(RefState)
|
||||
{
|
||||
}
|
||||
|
||||
XXX_Bethe_State::XXX_Bethe_State (const Heis_Chain& RefChain, int M)
|
||||
: Heis_Bethe_State(RefChain, M)
|
||||
{
|
||||
if (RefChain.Delta != 1.0) {
|
||||
cout << setprecision(16) << RefChain.Delta << endl;
|
||||
JSCerror("Delta != 1.0 in XXX_Bethe_State constructor");
|
||||
}
|
||||
}
|
||||
|
||||
XXX_Bethe_State::XXX_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase)
|
||||
: Heis_Bethe_State(RefChain, RefBase)
|
||||
{
|
||||
if (RefChain.Delta != 1.0) {
|
||||
cout << setprecision(16) << RefChain.Delta << endl;
|
||||
JSCerror("Delta != 1.0 in XXX_Bethe_State constructor");
|
||||
}
|
||||
}
|
||||
/*
|
||||
XXX_Bethe_State::XXX_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
|
||||
: Heis_Bethe_State(RefChain, base_id_ref, type_id_ref)
|
||||
{
|
||||
if (RefChain.Delta != 1.0) {
|
||||
cout << setprecision(16) << RefChain.Delta << endl;
|
||||
JSCerror("Delta != 1.0 in XXX_Bethe_State constructor");
|
||||
}
|
||||
}
|
||||
*/
|
||||
XXX_Bethe_State& XXX_Bethe_State::operator= (const XXX_Bethe_State& RefState)
|
||||
{
|
||||
if (this != &RefState) {
|
||||
chain = RefState.chain;
|
||||
base = RefState.base;
|
||||
//offsets = RefState.offsets;
|
||||
Ix2 = RefState.Ix2;
|
||||
lambda = RefState.lambda;
|
||||
BE = RefState.BE;
|
||||
diffsq = RefState.diffsq;
|
||||
conv = RefState.conv;
|
||||
iter = RefState.iter;
|
||||
iter_Newton = RefState.iter_Newton;
|
||||
E = RefState.E;
|
||||
iK = RefState.iK;
|
||||
K = RefState.K;
|
||||
lnnorm = RefState.lnnorm;
|
||||
//base_id = RefState.base_id;
|
||||
//type_id = RefState.type_id;
|
||||
//id = RefState.id;
|
||||
//maxid = RefState.maxid;
|
||||
//nparticles = RefState.nparticles;
|
||||
label = RefState.label;
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
// Member functions
|
||||
|
||||
void XXX_Bethe_State::Set_Free_lambdas()
|
||||
{
|
||||
// Sets all the rapidities to the solutions of the BAEs without scattering terms
|
||||
|
||||
for (int i = 0; i < chain.Nstrings; ++i) {
|
||||
|
||||
for (int alpha = 0; alpha < base[i]; ++alpha) {
|
||||
|
||||
lambda[i][alpha] = chain.Str_L[i] * 0.5 * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool XXX_Bethe_State::Check_Admissibility(char option)
|
||||
{
|
||||
// This function checks the admissibility of the Ix2's of a state:
|
||||
// returns false if there are higher strings with Ix2 = 0, a totally symmetric distribution of I's at each level,
|
||||
// and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE.
|
||||
|
||||
bool answer = true;
|
||||
//int test1, test3;
|
||||
Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
|
||||
|
||||
bool higher_string_on_zero = false;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
// The following line puts answer to true if there is at least one higher string with zero Ix2
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] > 2) && !(chain.Str_L[j] % 2))
|
||||
higher_string_on_zero = true;
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
|
||||
// NOTE: if base[j] == 0, Zero_at_level[j] remains false.
|
||||
}
|
||||
|
||||
bool symmetric_state = (*this).Check_Symmetry();
|
||||
|
||||
bool string_coincidence = false;
|
||||
// Checks that we have strings of equal length modulo 2 with Ix2 == 0, so equal rapidities, and inadmissibility
|
||||
for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
|
||||
for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
|
||||
if (Zero_at_level[j1] && Zero_at_level[j2] && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
|
||||
string_coincidence = true;
|
||||
}
|
||||
/*
|
||||
bool onep_onem_on_zero = false;
|
||||
if (option == 'm') { // for Smin, we also exclude symmetric states with 1+ and 1- strings on zero
|
||||
if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
|
||||
}
|
||||
*/
|
||||
answer = !(symmetric_state && (higher_string_on_zero || string_coincidence /*|| onep_onem_on_zero*/));
|
||||
|
||||
// Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
|
||||
|
||||
if (!answer) {
|
||||
E = 0.0;
|
||||
K = 0.0;
|
||||
conv = 0;
|
||||
iter = 0;
|
||||
iter_Newton = 0;
|
||||
lnnorm = -100.0;
|
||||
}
|
||||
|
||||
return(answer); // answer == true: nothing wrong with this Ix2_config
|
||||
}
|
||||
|
||||
void XXX_Bethe_State::Compute_BE (int j, int alpha)
|
||||
{
|
||||
// Fills in the BE members with the value of the Bethe equations.
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += atan(lambda[j][alpha] - lambda[k][beta]);
|
||||
|
||||
else sumtheta += 0.5 * Theta_XXX((lambda[j][alpha] - lambda[k][beta]), chain.Str_L[j], chain.Str_L[k]);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = 2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
}
|
||||
|
||||
void XXX_Bethe_State::Compute_BE ()
|
||||
{
|
||||
// Fills in the BE members with the value of the Bethe equations.
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += atan(lambda[j][alpha] - lambda[k][beta]);
|
||||
|
||||
else sumtheta += 0.5 * Theta_XXX((lambda[j][alpha] - lambda[k][beta]), chain.Str_L[j], chain.Str_L[k]);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = 2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DP XXX_Bethe_State::Iterate_BAE (int j, int alpha)
|
||||
{
|
||||
// Returns a new iteration value for lambda[j][alpha] given BE[j][alpha]
|
||||
|
||||
return(0.5 * chain.Str_L[j] * tan(0.5 *
|
||||
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
|
||||
(2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - BE[j][alpha])
|
||||
));
|
||||
}
|
||||
|
||||
/*
|
||||
void XXX_Bethe_State::Iterate_BAE ()
|
||||
{
|
||||
// Recalculates the rapidities by iterating Bethe equations
|
||||
|
||||
Lambda New_lambda(chain, base);
|
||||
DP sumtheta = 0.0;
|
||||
DP arg = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += atan(lambda[j][alpha] - lambda[k][beta]);
|
||||
|
||||
else sumtheta += 0.5 * Theta_XXX(lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k]);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
New_lambda[j][alpha] = 0.5 * chain.Str_L[j] * tan((PI * 0.5 * Ix2[j][alpha] + 0.5 * sumtheta)/chain.Nsites);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DP New_diffsq = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
New_diffsq += pow(New_lambda[j][alpha] - lambda[j][alpha], 2.0);
|
||||
lambda[j][alpha] = 1.0 * New_lambda[j][alpha] + 0.0 * lambda[j][alpha];
|
||||
}
|
||||
}
|
||||
|
||||
diffsq = New_diffsq;
|
||||
iter++;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void XXX_Bethe_State::Iterate_BAE_Newton ()
|
||||
{
|
||||
// does one step of a Newton method on the rapidities...
|
||||
|
||||
Vect_DP RHSBAE (0.0, base.Nraptot); // contains RHS of BAEs
|
||||
Vect_CX dlambda (0.0, base.Nraptot); // contains delta lambda computed from Newton's method
|
||||
SQMat_CX Gaudin (0.0, base.Nraptot);
|
||||
Vect_INT indx (base.Nraptot);
|
||||
DP sumtheta = 0.0;
|
||||
DP arg = 0.0;
|
||||
DP fn_arg = 0.0;
|
||||
DP olddiffsq = diffsq;
|
||||
|
||||
// Compute the RHS of the BAEs:
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += atan(lambda[j][alpha] - lambda[k][beta]);
|
||||
|
||||
else sumtheta += 0.5 * Theta_XXX((lambda[j][alpha] - lambda[k][beta]), chain.Str_L[j], chain.Str_L[k]);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
RHSBAE[index] = chain.Nsites * 2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - sumtheta - PI*Ix2[j][alpha];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
(*this).Build_Reduced_Gaudin_Matrix (Gaudin);
|
||||
|
||||
for (int i = 0; i < base.Nraptot; ++i) dlambda[i] = - RHSBAE[i];
|
||||
|
||||
DP d;
|
||||
ludcmp_CX (Gaudin, indx, d);
|
||||
lubksb_CX (Gaudin, indx, dlambda);
|
||||
|
||||
diffsq = 0.0;
|
||||
for (int i = 0; i < base.Nraptot; ++i) diffsq += norm(dlambda[i]);
|
||||
|
||||
// if we've converged, calculate the norm here, since the work has been done...
|
||||
|
||||
if (diffsq < chain.prec) {
|
||||
lnnorm = 0.0;
|
||||
for (int j = 0; j < base.Nraptot; j++) lnnorm += log(abs(Gaudin[j][j]));
|
||||
}
|
||||
|
||||
index = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
lambda[j][alpha] += real(dlambda[index]);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
iter_Newton++;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
bool XXX_Bethe_State::Check_Rapidities()
|
||||
{
|
||||
bool nonan = true;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) nonan *= !is_nan(lambda[j][alpha]);
|
||||
|
||||
return nonan;
|
||||
}
|
||||
|
||||
DP XXX_Bethe_State::String_delta ()
|
||||
{
|
||||
// Computes the sum of absolute value of \delta^{a, a+1} in string hypothesis, for a given Bethe eigenstate
|
||||
|
||||
DP delta = 0.0;
|
||||
|
||||
int occupied_strings = 0;
|
||||
for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
|
||||
|
||||
//if ((*this).conv == 0) delta = 1.0;
|
||||
|
||||
if (occupied_strings == 0) delta = 0.0;
|
||||
|
||||
else {
|
||||
|
||||
Vect_DP ln_deltadiff(0.0, 1000); // contains ln |delta^{a, a+1}|
|
||||
Vect_DP deltadiff(0.0, 1000); // contains |delta^{a, a+1}|
|
||||
|
||||
complex<DP> log_BAE_reg = 0.0;
|
||||
|
||||
for (int j = 0; j < (*this).chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < (*this).base[j]; ++alpha) {
|
||||
|
||||
ln_deltadiff = 0.0;
|
||||
|
||||
for (int a = 1; a <= (*this).chain.Str_L[j]; ++a) {
|
||||
|
||||
if ((*this).chain.Str_L[j] > 1) { // else the BAE are already 1
|
||||
|
||||
log_BAE_reg = DP((*this).chain.Nsites) * log(((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0))
|
||||
/((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int k = 0; k < (*this).chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < (*this).base[k]; ++beta)
|
||||
for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
|
||||
if ((j != k) || (alpha != beta) || (a != b - 1))
|
||||
|
||||
log_BAE_reg += log((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
|
||||
) - II );
|
||||
|
||||
if ((j != k) || (alpha != beta) || (a != b + 1))
|
||||
|
||||
log_BAE_reg -= log(((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
|
||||
)
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
|
||||
) + II );
|
||||
}
|
||||
|
||||
// The regular LHS of BAE is now defined. Now sum up the deltas...
|
||||
|
||||
if (a == 1) ln_deltadiff[0] = - real(log_BAE_reg);
|
||||
|
||||
else if (a < (*this).chain.Str_L[j]) ln_deltadiff[a - 1] = ln_deltadiff[a-2] - real(log_BAE_reg);
|
||||
|
||||
else if (a == (*this).chain.Str_L[j]) ln_deltadiff[a-1] = real(log_BAE_reg);
|
||||
|
||||
} // if ((*this).chain.Str_L[j] > 1)
|
||||
|
||||
} // for (int a = 1; ...
|
||||
|
||||
for (int a = 0; a < (*this).chain.Str_L[j]; ++a) {
|
||||
deltadiff[a] = ln_deltadiff[a] != 0.0 ? exp(ln_deltadiff[a]) : 0.0;
|
||||
delta += fabs(deltadiff[a]);
|
||||
}
|
||||
|
||||
} // alpha sum
|
||||
} // j sum
|
||||
|
||||
if (is_nan(delta)) delta = 1.0; // sentinel
|
||||
|
||||
} // else
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
void XXX_Bethe_State::Compute_Energy ()
|
||||
{
|
||||
DP sum = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum += chain.Str_L[j] / ( 4.0 * lambda[j][alpha] * lambda[j][alpha] + chain.Str_L[j] * chain.Str_L[j]);
|
||||
}
|
||||
}
|
||||
|
||||
sum *= - chain.J * 2.0;
|
||||
|
||||
E = sum;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
void XXX_Bethe_State::Compute_Momentum ()
|
||||
{
|
||||
int sum_Ix2 = 0;
|
||||
DP sum_M = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
sum_M += base[j];
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum_Ix2 += Ix2[j][alpha];
|
||||
}
|
||||
}
|
||||
|
||||
iK = (chain.Nsites/2) * int(sum_M) - (sum_Ix2/2);
|
||||
|
||||
while (iK >= chain.Nsites) iK -= chain.Nsites;
|
||||
while (iK < 0) iK += chain.Nsites;
|
||||
|
||||
K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
|
||||
|
||||
while (K >= 2.0*PI) K -= 2.0*PI;
|
||||
while (K < 0.0) K += 2.0*PI;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
void XXX_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
|
||||
{
|
||||
|
||||
if (Gaudin_Red.size() != base.Nraptot) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
|
||||
int index_jalpha;
|
||||
int index_kbeta;
|
||||
|
||||
DP sum_hbar_XXX = 0.0;
|
||||
|
||||
index_jalpha = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
index_kbeta = 0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta) {
|
||||
|
||||
if ((j == k) && (alpha == beta)) {
|
||||
|
||||
sum_hbar_XXX = 0.0;
|
||||
|
||||
for (int kp = 0; kp < chain.Nstrings; ++kp) {
|
||||
for (int betap = 0; betap < base[kp]; ++betap) {
|
||||
if (!((j == kp) && (alpha == betap)))
|
||||
sum_hbar_XXX
|
||||
+= ddlambda_Theta_XXX (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp]);
|
||||
}
|
||||
}
|
||||
|
||||
Gaudin_Red[index_jalpha][index_kbeta]
|
||||
= complex<DP> ( chain.Nsites * chain.Str_L[j]/(lambda[j][alpha] * lambda[j][alpha] + 0.25 * chain.Str_L[j] * chain.Str_L[j])
|
||||
- sum_hbar_XXX);
|
||||
}
|
||||
|
||||
else {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
Gaudin_Red[index_jalpha][index_kbeta] =
|
||||
complex<DP> ( 2.0/(pow(lambda[j][alpha] - lambda[k][beta], 2.0) + 1.0));
|
||||
|
||||
else
|
||||
Gaudin_Red[index_jalpha][index_kbeta] =
|
||||
complex<DP> (ddlambda_Theta_XXX (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k]));
|
||||
}
|
||||
index_kbeta++;
|
||||
}
|
||||
}
|
||||
index_jalpha++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool XXX_Bethe_State::Check_Finite_rap ()
|
||||
{
|
||||
bool answer = true;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
if (fabs(lambda[j][alpha]) > 1.0e6) answer = false;
|
||||
}
|
||||
}
|
||||
|
||||
return(answer);
|
||||
}
|
||||
|
||||
// ****************************************************************************************************
|
||||
|
||||
// non-member functions
|
||||
|
||||
DP Theta_XXX (DP lambda, int nj, int nk)
|
||||
{
|
||||
DP result;
|
||||
|
||||
if ((nj == 1) && (nk == 1)) result = 2.0 * atan(lambda);
|
||||
|
||||
else {
|
||||
|
||||
result = (nj == nk) ? 0.0 : 2.0 * atan(2.0 * lambda/fabs(nj - nk));
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 4.0 * atan(2.0 * lambda/(fabs(nj - nk) + 2*a));
|
||||
|
||||
result += 2.0 * atan(2.0 * lambda/(nj + nk));
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DP ddlambda_Theta_XXX (DP lambda, int nj, int nk)
|
||||
{
|
||||
int n = abs(nj - nk);
|
||||
|
||||
DP result = (nj == nk) ? 0.0 : DP(n)/(lambda * lambda + 0.25 * n * n);
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * (n + 2.0*a)
|
||||
/ (lambda * lambda + 0.25 * (n + 2.0*a) * (n + 2.0*a));
|
||||
|
||||
result += DP(nj + nk)/(lambda * lambda + 0.25 * (nj + nk) * (nj + nk));
|
||||
|
||||
return (result);
|
||||
}
|
||||
/*
|
||||
DP ddlambda_Theta_XXX (DP lambda, int nj, int nk)
|
||||
{
|
||||
DP result = (nj == nk) ? 0.0 : DP(nj - nk)/(lambda * lambda + 0.25 * (nj - nk) * (nj - nk));
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * (nj - nk + 2.0*a) * (nj - nk + 2.0*a)
|
||||
/ (lambda * lambda + 0.25 * (nj - nk + 2.0*a) * (nj - nk + 2.0*a));
|
||||
|
||||
result += DP(nj + nk)/(lambda * lambda + 0.25 * (nj + nk) * (nj + nk));
|
||||
|
||||
return (result);
|
||||
}
|
||||
*/
|
||||
|
||||
XXX_Bethe_State Add_Particle_at_Center (const XXX_Bethe_State& RefState)
|
||||
{
|
||||
if (2*RefState.base.Mdown == RefState.chain.Nsites)
|
||||
JSCerror("Trying to add a down spin to a zero-magnetized chain in Add_Particle_at_Center.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] + 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXX_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Add a quantum number in middle (explicitly: to right of index M[0]/2)
|
||||
// and shift quantum numbers by half-integer away from added one:
|
||||
ReturnState.Ix2[0][RefState.base.Nrap[0]/2] = RefState.Ix2[0][RefState.base.Nrap[0]/2] - 1;
|
||||
for (int i = 0; i < RefState.base.Nrap[0] + 1; ++i)
|
||||
ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] = RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
|
||||
XXX_Bethe_State Remove_Particle_at_Center (const XXX_Bethe_State& RefState)
|
||||
{
|
||||
if (RefState.base.Nrap[0] == 0)
|
||||
JSCerror("Trying to remove a down spin in an empty Nrap[0] state.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] - 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXX_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Remove midmost and shift quantum numbers by half-integer towards removed one:
|
||||
for (int i = 0; i < RefState.base.Nrap[0]-1; ++i)
|
||||
ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,646 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/XXZ_Bethe_State.cc
|
||||
|
||||
Purpose: Defines all functions for XXZ_Bethe_State
|
||||
|
||||
******************************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// Function prototypes
|
||||
|
||||
inline DP fbar_XXZ (DP lambda, int par, DP tannzetaover2);
|
||||
DP Theta_XXZ (DP lambda, int nj, int nk, int parj, int park, DP* tannzetaover2);
|
||||
DP hbar_XXZ (DP lambda, int n, int par, DP* si_n_anis_over_2);
|
||||
DP ddlambda_Theta_XXZ (DP lambda, int nj, int nk, int parj, int park, DP* si_n_anis_over_2);
|
||||
|
||||
|
||||
//***************************************************************************************************
|
||||
|
||||
// Function definitions: class XXZ_Bethe_State
|
||||
|
||||
XXZ_Bethe_State::XXZ_Bethe_State ()
|
||||
: Heis_Bethe_State(), sinhlambda(Lambda(chain, 1)), coshlambda(Lambda(chain, 1)), tanhlambda(Lambda(chain, 1))
|
||||
{};
|
||||
|
||||
XXZ_Bethe_State::XXZ_Bethe_State (const XXZ_Bethe_State& RefState) // copy constructor
|
||||
: Heis_Bethe_State(RefState), sinhlambda(Lambda(RefState.chain, RefState.base)), coshlambda(Lambda(RefState.chain, RefState.base)),
|
||||
tanhlambda(Lambda(RefState.chain, RefState.base))
|
||||
{
|
||||
// copy arrays into new ones
|
||||
|
||||
//cout << "Calling XXZ state copy constructor." << endl;
|
||||
for (int j = 0; j < RefState.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < RefState.base[j]; ++j) {
|
||||
sinhlambda[j][alpha] = RefState.sinhlambda[j][alpha];
|
||||
coshlambda[j][alpha] = RefState.coshlambda[j][alpha];
|
||||
tanhlambda[j][alpha] = RefState.tanhlambda[j][alpha];
|
||||
}
|
||||
}
|
||||
//cout << "Done calling XXZ state copy constructor." << endl;
|
||||
}
|
||||
|
||||
XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, int M)
|
||||
: Heis_Bethe_State(RefChain, M),
|
||||
sinhlambda(Lambda(RefChain, M)), coshlambda(Lambda(RefChain, M)), tanhlambda(Lambda(RefChain, M))
|
||||
{
|
||||
//cout << "Here in XXZ BS constructor." << endl;
|
||||
//cout << (*this).lambda[0][0] << endl;
|
||||
//cout << "OK" << endl;
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) JSCerror("Delta out of range in XXZ_Bethe_State constructor");
|
||||
}
|
||||
|
||||
XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase)
|
||||
: Heis_Bethe_State(RefChain, RefBase),
|
||||
sinhlambda(Lambda(RefChain, RefBase)), coshlambda(Lambda(RefChain, RefBase)), tanhlambda(Lambda(RefChain, RefBase))
|
||||
{
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) JSCerror("Delta out of range in XXZ_Bethe_State constructor");
|
||||
}
|
||||
/*
|
||||
XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
|
||||
: Heis_Bethe_State(RefChain, base_id_ref, type_id_ref),
|
||||
sinhlambda(Lambda(chain, base)), coshlambda(Lambda(chain, base)), tanhlambda(Lambda(chain, base))
|
||||
{
|
||||
if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) JSCerror("Delta out of range in XXZ_Bethe_State constructor");
|
||||
}
|
||||
*/
|
||||
|
||||
XXZ_Bethe_State& XXZ_Bethe_State::operator= (const XXZ_Bethe_State& RefState)
|
||||
{
|
||||
if (this != &RefState) {
|
||||
chain = RefState.chain;
|
||||
base = RefState.base;
|
||||
//offsets = RefState.offsets;
|
||||
Ix2 = RefState.Ix2;
|
||||
lambda = RefState.lambda;
|
||||
BE = RefState.BE;
|
||||
diffsq = RefState.diffsq;
|
||||
conv = RefState.conv;
|
||||
iter = RefState.iter;
|
||||
iter_Newton = RefState.iter_Newton;
|
||||
E = RefState.E;
|
||||
iK = RefState.iK;
|
||||
K = RefState.K;
|
||||
lnnorm = RefState.lnnorm;
|
||||
//base_id = RefState.base_id;
|
||||
//type_id = RefState.type_id;
|
||||
//id = RefState.id;
|
||||
//maxid = RefState.maxid;
|
||||
//nparticles = RefState.nparticles;
|
||||
label = RefState.label;
|
||||
|
||||
sinhlambda = RefState.sinhlambda;
|
||||
coshlambda = RefState.coshlambda;
|
||||
tanhlambda = RefState.tanhlambda;
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
// Member functions
|
||||
|
||||
void XXZ_Bethe_State::Set_Free_lambdas()
|
||||
{
|
||||
// Sets all the rapidities to the solutions of the BAEs without scattering terms
|
||||
|
||||
DP x = 0.0;
|
||||
for (int i = 0; i < chain.Nstrings; ++i) {
|
||||
|
||||
for (int alpha = 0; alpha < base[i]; ++alpha) {
|
||||
|
||||
if (chain.par[i] == 1) {
|
||||
//lambda[i][alpha] = atanh(tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites));
|
||||
x = tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites);
|
||||
lambda[i][alpha] = atanh(x/sqrt(1.0 + x*x)); // lambda then always initiated real
|
||||
}
|
||||
|
||||
else if (chain.par[i] == -1) {
|
||||
//lambda[i][alpha] = atanh(-tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis));
|
||||
x = -tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis);
|
||||
lambda[i][alpha] = atanh(x/sqrt(1.0 + x*x)); // lambda then always initiated real
|
||||
}
|
||||
|
||||
else JSCerror("Invalid parities in Set_Free_lambdas.");
|
||||
//cout << tan(chain.Str_L[i] * 0.5 * chain.anis) << endl;
|
||||
//cout << "Set_Free_lambdas: " << i << "\t" << alpha << "\t" << lambda[i][alpha] << "\t" << tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites) << endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_Bethe_State::Compute_sinhlambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) sinhlambda[j][alpha] = sinh(lambda[j][alpha]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_Bethe_State::Compute_coshlambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) coshlambda[j][alpha] = cosh(lambda[j][alpha]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_Bethe_State::Compute_tanhlambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) tanhlambda[j][alpha] = tanh(lambda[j][alpha]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool XXZ_Bethe_State::Check_Admissibility(char option)
|
||||
{
|
||||
// This function checks the admissibility of the Ix2's of a state:
|
||||
// returns false if there are higher strings with Ix2 = 0, a totally symmetric distribution of I's at each level,
|
||||
// and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE.
|
||||
|
||||
bool answer = true;
|
||||
Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
|
||||
|
||||
bool higher_string_on_zero = false;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
// The following line puts answer to true if there is at least one higher string with zero Ix2
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] >= 2) /*&& !(chain.Str_L[j] % 2)*/)
|
||||
higher_string_on_zero = true;
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
|
||||
// NOTE: if base[j] == 0, Zero_at_level[j] remains false.
|
||||
}
|
||||
|
||||
// check symmetry of Ix2 at each level, if there exists a potentially risky Ix2...
|
||||
|
||||
bool symmetric_state = (*this).Check_Symmetry();
|
||||
|
||||
bool string_coincidence = false;
|
||||
for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
|
||||
for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
|
||||
if (Zero_at_level[j1] && Zero_at_level[j2] && (chain.par[j1] == chain.par[j2]) && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
|
||||
string_coincidence = true;
|
||||
}
|
||||
|
||||
bool M_odd_and_onep_on_zero = false;
|
||||
if (option == 'z') { // for Sz, if M is odd, exclude symmetric states with a 1+ on zero
|
||||
// (zero rapidities in left and right states, so FF det not defined).
|
||||
bool is_ground_state = base.Nrap[0] == base.Mdown && Ix2[0][0] == -(base.Mdown - 1) && Ix2[0][base.Mdown-1] == base.Mdown - 1;
|
||||
if (Zero_at_level[0] && (base.Mdown % 2) && !is_ground_state) M_odd_and_onep_on_zero = true;
|
||||
}
|
||||
|
||||
bool onep_onem_on_zero = false;
|
||||
if (option == 'm' || option == 'p') { // for Smin, we also exclude symmetric states with 1+ and 1- strings on zero
|
||||
if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
|
||||
}
|
||||
|
||||
answer = !(symmetric_state && (higher_string_on_zero || string_coincidence || onep_onem_on_zero || M_odd_and_onep_on_zero));
|
||||
|
||||
// Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
|
||||
|
||||
if (!answer) {
|
||||
E = 0.0;
|
||||
K = 0.0;
|
||||
conv = 0;
|
||||
iter = 0;
|
||||
iter_Newton = 0;
|
||||
lnnorm = -100.0;
|
||||
}
|
||||
|
||||
return(answer); // answer == true: nothing wrong with this Ix2_config
|
||||
}
|
||||
|
||||
void XXZ_Bethe_State::Compute_BE (int j, int alpha)
|
||||
{
|
||||
tanhlambda[j][alpha] = tanh(lambda[j][alpha]);
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
for (int k = 0; k < chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < base[k]; ++beta) {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += (chain.par[j] == chain.par[k])
|
||||
? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
|
||||
: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
|
||||
else sumtheta += 0.5 * Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
: -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
|
||||
}
|
||||
|
||||
void XXZ_Bethe_State::Compute_BE ()
|
||||
{
|
||||
// Fills in the BE members with the value of the Bethe equations.
|
||||
|
||||
(*this).Compute_tanhlambda();
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < base[k]; ++beta) {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += (chain.par[j] == chain.par[k])
|
||||
? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
|
||||
: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
|
||||
else sumtheta += 0.5 * Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
: -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
|
||||
//if (is_nan(BE[j][alpha])) cout << "BE nan: " << j << "\t" << alpha << "\t" << lambda[j][alpha] << "\t" << tanhlambda[j][alpha] << endl;
|
||||
}
|
||||
}
|
||||
|
||||
DP XXZ_Bethe_State::Iterate_BAE (int j, int alpha)
|
||||
{
|
||||
// Returns a new iteration value for lambda[j][alpha] given tanhlambda and BE Lambdas
|
||||
// Assumes that tanhlambda[][] and BE[][] have been computed.
|
||||
|
||||
DP new_lambda = 0.0;
|
||||
DP arg = 0.0;
|
||||
|
||||
if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]]
|
||||
* tan(0.5 *
|
||||
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
|
||||
(2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha])
|
||||
);
|
||||
|
||||
else if (chain.par[j] == -1) arg = -tan(0.5 *
|
||||
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites)
|
||||
(-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha]))
|
||||
/chain.ta_n_anis_over_2[chain.Str_L[j]];
|
||||
|
||||
if (fabs(arg) < 1.0) {
|
||||
new_lambda = atanh(arg);
|
||||
}
|
||||
|
||||
else {
|
||||
new_lambda = lambda[j][alpha]; // back to drawing board...
|
||||
int block = 0; // counter to prevent runaway while loop
|
||||
DP new_tanhlambda = 0.0;
|
||||
DP sumtheta = 0.0;
|
||||
arg = 10.0; // reset value to start while loop
|
||||
while ((fabs(arg) > 1.0) && (block++ < 100)) { // recompute the diverging root on its own...
|
||||
new_lambda *= 1.01; // try to go slowly towards infinity...
|
||||
new_tanhlambda = tanh(new_lambda);
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += (chain.par[j] == chain.par[k])
|
||||
? atan((new_tanhlambda - tanhlambda[k][beta])/((1.0 - new_tanhlambda * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2]))
|
||||
: - atan(((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ;
|
||||
else sumtheta += 0.5 * Theta_XXZ((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(0.5 * (PI * Ix2[j][alpha] + sumtheta)/chain.Nsites);
|
||||
|
||||
else if (chain.par[j] == -1) arg = -tan(0.5 * (PI * Ix2[j][alpha] + sumtheta)/chain.Nsites)/chain.ta_n_anis_over_2[chain.Str_L[j]];
|
||||
|
||||
else JSCerror("Invalid parities in Iterate_BAE.");
|
||||
|
||||
}
|
||||
|
||||
if (fabs(arg) < 1.0) {
|
||||
new_lambda = atanh(arg);
|
||||
}
|
||||
|
||||
//else cout << "Rapidity blows up !\t" << lambda[j][alpha] << "\t" << new_lambda << endl;
|
||||
} // else
|
||||
|
||||
return(new_lambda);
|
||||
}
|
||||
|
||||
bool XXZ_Bethe_State::Check_Rapidities()
|
||||
{
|
||||
bool nonan = true;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) nonan *= !is_nan(lambda[j][alpha]);
|
||||
|
||||
return nonan;
|
||||
}
|
||||
|
||||
DP XXZ_Bethe_State::String_delta ()
|
||||
{
|
||||
// Computes the sum of absolute value of \delta^{a, a+1} in string hypothesis, for a given bethe eigenstate
|
||||
|
||||
DP delta = 0.0;
|
||||
|
||||
int occupied_strings = 0;
|
||||
for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
|
||||
|
||||
//if ((*this).conv == 0) delta = 1.0;
|
||||
|
||||
if (occupied_strings == 0) delta = 0.0;
|
||||
|
||||
else {
|
||||
|
||||
Vect_DP ln_deltadiff(0.0, 1000); // contains ln |delta^{a, a+1}|
|
||||
Vect_DP deltadiff(0.0, 1000); // contains |delta^{a, a+1}|
|
||||
|
||||
complex<DP> log_BAE_reg = 0.0;
|
||||
|
||||
for (int j = 0; j < (*this).chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < (*this).base[j]; ++alpha) {
|
||||
|
||||
ln_deltadiff = 0.0;
|
||||
|
||||
for (int a = 1; a <= (*this).chain.Str_L[j]; ++a) {
|
||||
|
||||
if ((*this).chain.Str_L[j] > 1) { // else the BAE are already 1
|
||||
|
||||
log_BAE_reg = DP((*this).chain.Nsites) * log(sinh((*this).lambda[j][alpha]
|
||||
+ 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
|
||||
/sinh((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j])));
|
||||
|
||||
for (int k = 0; k < (*this).chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < (*this).base[k]; ++beta)
|
||||
for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
|
||||
if ((j != k) || (alpha != beta) || (a != b - 1))
|
||||
|
||||
log_BAE_reg += log(sinh(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[k])) - II * (*this).chain.anis));
|
||||
|
||||
if ((j != k) || (alpha != beta) || (a != b + 1))
|
||||
|
||||
log_BAE_reg -= log(sinh(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
|
||||
+ 0.25 * II * PI * (1.0 - (*this).chain.par[k])) + II * (*this).chain.anis));
|
||||
}
|
||||
|
||||
// The regular LHS of BAE is now defined. Now sum up the deltas...
|
||||
|
||||
if (a == 1) ln_deltadiff[0] = - real(log_BAE_reg);
|
||||
|
||||
else if (a < (*this).chain.Str_L[j]) ln_deltadiff[a - 1] = ln_deltadiff[a-2] - real(log_BAE_reg);
|
||||
|
||||
else if (a == (*this).chain.Str_L[j]) ln_deltadiff[a-1] = real(log_BAE_reg);
|
||||
|
||||
} // if ((*this).chain.Str_L[j] > 1)
|
||||
|
||||
} // for (int a = 1; ...
|
||||
|
||||
for (int a = 0; a < (*this).chain.Str_L[j]; ++a) {
|
||||
deltadiff[a] = ln_deltadiff[a] != 0.0 ? exp(ln_deltadiff[a]) : 0.0;
|
||||
delta += fabs(deltadiff[a]);
|
||||
}
|
||||
|
||||
} // alpha sum
|
||||
} // j sum
|
||||
|
||||
if (is_nan(delta)) delta = 1.0; // sentinel
|
||||
|
||||
} // else
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
void XXZ_Bethe_State::Compute_Energy ()
|
||||
{
|
||||
DP sum = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum += sin(chain.Str_L[j] * chain.anis) / (chain.par[j] * cosh(2.0 * lambda[j][alpha]) - cos(chain.Str_L[j] * chain.anis));
|
||||
}
|
||||
}
|
||||
|
||||
sum *= - chain.J * sin(chain.anis);
|
||||
|
||||
E = sum;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
void XXZ_Bethe_State::Compute_Momentum ()
|
||||
{
|
||||
int sum_Ix2 = 0;
|
||||
DP sum_M = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
sum_M += 0.5 * (1.0 + chain.par[j]) * base[j];
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum_Ix2 += Ix2[j][alpha];
|
||||
}
|
||||
}
|
||||
|
||||
iK = (chain.Nsites/2) * int(sum_M + 0.1) - (sum_Ix2/2); // + 0.1: for safety...
|
||||
|
||||
while (iK >= chain.Nsites) iK -= chain.Nsites;
|
||||
while (iK < 0) iK += chain.Nsites;
|
||||
|
||||
K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
|
||||
|
||||
while (K >= 2.0*PI) K -= 2.0*PI;
|
||||
while (K < 0.0) K += 2.0*PI;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
void XXZ_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
|
||||
{
|
||||
|
||||
if (Gaudin_Red.size() != base.Nraptot) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
|
||||
int index_jalpha;
|
||||
int index_kbeta;
|
||||
|
||||
DP sum_hbar_XXZ = 0.0;
|
||||
|
||||
DP sinzetasq = pow(sin(chain.anis), 2.0);
|
||||
|
||||
(*this).Compute_sinhlambda();
|
||||
(*this).Compute_coshlambda();
|
||||
|
||||
index_jalpha = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
index_kbeta = 0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta) {
|
||||
|
||||
if ((j == k) && (alpha == beta)) {
|
||||
|
||||
sum_hbar_XXZ = 0.0;
|
||||
|
||||
for (int kp = 0; kp < chain.Nstrings; ++kp) {
|
||||
for (int betap = 0; betap < base[kp]; ++betap) {
|
||||
if (!((j == kp) && (alpha == betap)))
|
||||
sum_hbar_XXZ
|
||||
+= ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp], chain.par[j], chain.par[kp],
|
||||
chain.si_n_anis_over_2);
|
||||
}
|
||||
}
|
||||
|
||||
Gaudin_Red[index_jalpha][index_kbeta]
|
||||
= complex<DP> ( chain.Nsites * hbar_XXZ (lambda[j][alpha], chain.Str_L[j], chain.par[j], chain.si_n_anis_over_2) - sum_hbar_XXZ);
|
||||
}
|
||||
|
||||
else {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
Gaudin_Red[index_jalpha][index_kbeta] =
|
||||
complex<DP> ((chain.par[j] * chain.par[k] == 1)
|
||||
? chain.si_n_anis_over_2[4]/(pow(sinhlambda[j][alpha] * coshlambda[k][beta]
|
||||
- coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq)
|
||||
: chain.si_n_anis_over_2[4]/(-pow(coshlambda[j][alpha] * coshlambda[k][beta]
|
||||
- sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) );
|
||||
else
|
||||
Gaudin_Red[index_jalpha][index_kbeta] = complex<DP> (ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k],
|
||||
chain.par[j], chain.par[k], chain.si_n_anis_over_2));
|
||||
}
|
||||
index_kbeta++;
|
||||
}
|
||||
}
|
||||
index_jalpha++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// ****************************************************************************************************
|
||||
|
||||
// non-member functions
|
||||
|
||||
inline DP fbar_XXZ (DP tanhlambda, int par, DP tannzetaover2)
|
||||
{
|
||||
DP result = 0.0;
|
||||
|
||||
if (par == 1) result = 2.0 * atan(tanhlambda/tannzetaover2);
|
||||
|
||||
else if (par == -1) result = -2.0 * atan(tanhlambda * tannzetaover2);
|
||||
|
||||
else JSCerror("Faulty parity in fbar_XXZ.");
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DP Theta_XXZ (DP tanhlambda, int nj, int nk, int parj, int park, DP* tannzetaover2)
|
||||
{
|
||||
DP result = 0.0;
|
||||
|
||||
if ((nj == 1) && (nk == 1)) result = fbar_XXZ(tanhlambda, parj*park, tannzetaover2[2]);
|
||||
|
||||
else {
|
||||
|
||||
result = (nj == nk) ? 0.0 : fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk)]);
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk) + 2*a]);
|
||||
|
||||
result += fbar_XXZ(tanhlambda, parj*park, tannzetaover2[nj + nk]);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DP hbar_XXZ (DP lambda, int n, int par, DP* si_n_anis_over_2)
|
||||
{
|
||||
DP result = 0.0;
|
||||
|
||||
if (par == 1) result = si_n_anis_over_2[2*n]/(pow(sinh(lambda), 2.0) + pow(si_n_anis_over_2[n], 2.0));
|
||||
|
||||
else if (par == -1) result = si_n_anis_over_2[2*n]/(-pow(cosh(lambda), 2.0) + pow(si_n_anis_over_2[n], 2.0));
|
||||
|
||||
else JSCerror("Faulty parity in hbar_XXZ.");
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DP ddlambda_Theta_XXZ (DP lambda, int nj, int nk, int parj, int park, DP* si_n_anis_over_2)
|
||||
{
|
||||
DP result = (nj == nk) ? 0.0 : hbar_XXZ(lambda, fabs(nj - nk), parj*park, si_n_anis_over_2);
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * hbar_XXZ(lambda, fabs(nj - nk) + 2*a, parj*park, si_n_anis_over_2);
|
||||
|
||||
result += hbar_XXZ(lambda, nj + nk, parj*park, si_n_anis_over_2);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
XXZ_Bethe_State Add_Particle_at_Center (const XXZ_Bethe_State& RefState)
|
||||
{
|
||||
if (2*RefState.base.Mdown == RefState.chain.Nsites)
|
||||
JSCerror("Trying to add a down spin to a zero-magnetized chain in Add_Particle_at_Center.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] + 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXZ_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Add a quantum number in middle (explicitly: to right of index M[0]/2)
|
||||
// and shift quantum numbers by half-integer away from added one:
|
||||
ReturnState.Ix2[0][RefState.base.Nrap[0]/2] = RefState.Ix2[0][RefState.base.Nrap[0]/2] - 1;
|
||||
for (int i = 0; i < RefState.base.Nrap[0] + 1; ++i)
|
||||
ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] = RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
|
||||
XXZ_Bethe_State Remove_Particle_at_Center (const XXZ_Bethe_State& RefState)
|
||||
{
|
||||
if (RefState.base.Nrap[0] == 0)
|
||||
JSCerror("Trying to remove a down spin in an empty Nrap[0] state.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] - 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXZ_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Remove midmost and shift quantum numbers by half-integer towards removed one:
|
||||
for (int i = 0; i < RefState.base.Nrap[0]-1; ++i)
|
||||
ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,814 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
File: src/HEIS/XXZ_gpd_Bethe_State.cc
|
||||
|
||||
Purpose: Defines all functions for XXZ_gpd_Bethe_State
|
||||
|
||||
******************************************************************/
|
||||
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
// Function prototypes
|
||||
|
||||
inline DP fbar_XXZ_gpd (DP lambda, int par, DP tanhnetaover2);
|
||||
DP Theta_XXZ_gpd (DP lambda, int nj, int nk, DP* tanhnetaover2);
|
||||
DP hbar_XXZ_gpd (DP lambda, int n, DP* si_n_anis_over_2);
|
||||
DP ddlambda_Theta_XXZ_gpd (DP lambda, int nj, int nk, DP* si_n_anis_over_2);
|
||||
|
||||
|
||||
//***************************************************************************************************
|
||||
|
||||
// Function definitions: class XXZ_gpd_Bethe_State
|
||||
|
||||
XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State ()
|
||||
: Heis_Bethe_State(), sinlambda(Lambda(chain, 1)), coslambda(Lambda(chain, 1)), tanlambda(Lambda(chain, 1))
|
||||
{};
|
||||
|
||||
XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const XXZ_gpd_Bethe_State& RefState) // copy constructor
|
||||
: Heis_Bethe_State(RefState),
|
||||
sinlambda(Lambda(RefState.chain, RefState.base)), coslambda(Lambda(RefState.chain, RefState.base)),
|
||||
tanlambda(Lambda(RefState.chain, RefState.base))
|
||||
{
|
||||
// copy arrays into new ones
|
||||
|
||||
for (int j = 0; j < RefState.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < RefState.base[j]; ++j) {
|
||||
sinlambda[j][alpha] = RefState.sinlambda[j][alpha];
|
||||
coslambda[j][alpha] = RefState.coslambda[j][alpha];
|
||||
tanlambda[j][alpha] = RefState.tanlambda[j][alpha];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, int M)
|
||||
: Heis_Bethe_State(RefChain, M),
|
||||
sinlambda(Lambda(RefChain, M)), coslambda(Lambda(RefChain, M)), tanlambda(Lambda(RefChain, M))
|
||||
{
|
||||
if (RefChain.Delta <= 1.0) JSCerror("Delta too low in XXZ_gpd_Bethe_State constructor");
|
||||
}
|
||||
|
||||
XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase)
|
||||
: Heis_Bethe_State(RefChain, RefBase),
|
||||
sinlambda(Lambda(RefChain, RefBase)), coslambda(Lambda(RefChain, RefBase)),
|
||||
tanlambda(Lambda(RefChain, RefBase))
|
||||
{
|
||||
if (RefChain.Delta <= 1.0) JSCerror("Delta too low in XXZ_gpd_Bethe_State constructor");
|
||||
}
|
||||
/*
|
||||
XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
|
||||
: Heis_Bethe_State(RefChain, base_id_ref, type_id_ref),
|
||||
sinlambda(Lambda(chain, base)), coslambda(Lambda(chain, base)), tanlambda(Lambda(chain, base))
|
||||
{
|
||||
if (RefChain.Delta <= 1.0) JSCerror("Delta too low in XXZ_gpd_Bethe_State constructor");
|
||||
}
|
||||
*/
|
||||
XXZ_gpd_Bethe_State& XXZ_gpd_Bethe_State::operator= (const XXZ_gpd_Bethe_State& RefState)
|
||||
{
|
||||
if (this != &RefState) {
|
||||
chain = RefState.chain;
|
||||
base = RefState.base;
|
||||
//offsets = RefState.offsets;
|
||||
Ix2 = RefState.Ix2;
|
||||
lambda = RefState.lambda;
|
||||
BE = RefState.BE;
|
||||
diffsq = RefState.diffsq;
|
||||
conv = RefState.conv;
|
||||
iter = RefState.iter;
|
||||
iter_Newton = RefState.iter_Newton;
|
||||
E = RefState.E;
|
||||
iK = RefState.iK;
|
||||
K = RefState.K;
|
||||
lnnorm = RefState.lnnorm;
|
||||
//base_id = RefState.base_id;
|
||||
//type_id = RefState.type_id;
|
||||
//id = RefState.id;
|
||||
//maxid = RefState.maxid;
|
||||
//nparticles = RefState.nparticles;
|
||||
label = RefState.label;
|
||||
|
||||
sinlambda = RefState.sinlambda;
|
||||
coslambda = RefState.coslambda;
|
||||
tanlambda = RefState.tanlambda;
|
||||
}
|
||||
return(*this);
|
||||
}
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
void XXZ_gpd_Bethe_State::Set_Free_lambdas()
|
||||
{
|
||||
// Sets all the rapidities to the solutions of the BAEs without scattering terms
|
||||
|
||||
for (int i = 0; i < chain.Nstrings; ++i) {
|
||||
|
||||
for (int alpha = 0; alpha < base[i]; ++alpha) {
|
||||
|
||||
lambda[i][alpha] = atan((tanh(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_sinlambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) sinlambda[j][alpha] = sin(lambda[j][alpha]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_coslambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) coslambda[j][alpha] = cos(lambda[j][alpha]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_tanlambda()
|
||||
{
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
tanlambda[j][alpha] = tan(lambda[j][alpha]);
|
||||
//if (lambda[j][alpha] > 0.5*PI) cout << "Rapidity higher than 0.5*PI: j = " << j << "\talpha = " << alpha << "\trap = " << lambda[j][alpha] << "\ttan = " << tanlambda[j][alpha] << endl;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool XXZ_gpd_Bethe_State::Check_Admissibility(char option)
|
||||
{
|
||||
// This function checks the admissibility of the Ix2's of a state:
|
||||
// returns false if there are higher strings with Ix2 = 0, a totally symmetric distribution of I's at each level,
|
||||
// and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE.
|
||||
|
||||
bool answer = true;
|
||||
Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
|
||||
|
||||
/*
|
||||
Vect<bool> min_Ix2_max_busy(false, chain.Nstrings);
|
||||
Vect<bool> plus_Ix2_max_busy(false, chain.Nstrings);
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
if (Ix2[j][alpha] == -base.Ix2_max[j]) min_Ix2_max_busy[j] = true;
|
||||
if (Ix2[j][alpha] == base.Ix2_max[j]) plus_Ix2_max_busy[j] = true;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
// State is not admissible if this is false: -N/2 + 1 \leq \sum I^j_{\alpha} \leq N
|
||||
int sum_all_Ix2 = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum_all_Ix2 += Ix2[j][alpha];
|
||||
}
|
||||
if (sum_all_Ix2 > chain.Nsites || sum_all_Ix2 <= -chain.Nsites) {
|
||||
cout << "\tSum Ix2 out of fundamental interval: sum_all_Ix2 = " << sum_all_Ix2 << "\tfor N = " << chain.Nsites << endl;
|
||||
return(false);
|
||||
}
|
||||
*/
|
||||
//Deactivated 2014 06 11, put in Heis_Form_Factor_Entry.cc
|
||||
/*
|
||||
// State is not admissible if I_max > 1/2 (N - \sum_k t_{jk} M_k) or I_min < -1/2 (N - sum_k...) + 1 at any level:
|
||||
int sum1 = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
sum1 = 0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
sum1 += base[k] * (2 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1 : 0));
|
||||
}
|
||||
// Define limits...
|
||||
//if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1;
|
||||
|
||||
// This almost does it: only missing are the states with one on -PI/2 and one on PI/2
|
||||
if (base[j] >= 1 && (Ix2[j][0] <= -(chain.Nsites - sum1) ||
|
||||
(Ix2[j][base[j] - 1] - Ix2[j][0]) > 2*(chain.Nsites - sum1))) {
|
||||
//cout << "\tAn Ix2 is out of interval at level " << j << endl;
|
||||
//cout << Ix2[j][base[j] - 1] << "\t" << Ix2[j][0] << "\t" << chain.Nsites << "\t" << sum1 << endl;
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// State is not admissible if both a min_ and plus_Ix2_max are busy simultaneously:
|
||||
bool is_a_min_Ix2_max_busy = false;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) if (min_Ix2_max_busy[j]) is_a_min_Ix2_max_busy = true;
|
||||
bool is_a_plus_Ix2_max_busy = false;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) if (plus_Ix2_max_busy[j]) is_a_plus_Ix2_max_busy = true;
|
||||
*/
|
||||
/*
|
||||
// State is not admissible if all min_Ix2_max are busy simultaneously:
|
||||
bool any_min_Ix2_max_free = false;
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
if (base[j] > 0 && !min_Ix2_max_busy[j]) any_min_Ix2_max_free = true;
|
||||
if (!any_min_Ix2_max_free) return(false);
|
||||
*/
|
||||
/*
|
||||
// State is not admissible if -Ix2_max, -Ix2_max + 2, ..., -Ix2_max + 2*(Str_L - 1) are busy:
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
if (base[j] > 0 && Ix2[j][0] <= -base.Ix2_max[j] + 2*(chain.Str_L[j] - 1))
|
||||
return(false);
|
||||
// Almost correct with above !
|
||||
// State is not admissible if Ix2_max - 2, ..., Ix2_max - 2*(Str_L - 2) are busy (NB: one slot more than on left):
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
if (base[j] > 0 && Ix2[j][base[j] - 1] >= base.Ix2_max[j] - 2*(chain.Str_L[j] - 2))
|
||||
return(false);
|
||||
*/
|
||||
|
||||
// Check that at all at least doubly occupied levels, the difference between max and min quantum numbers
|
||||
// is strictly smaller than 2*Ix2_max - 2, so that lambda_max - lambda_min < PI at each level:
|
||||
//for (int j = 0; j < chain.Nstrings; ++j)
|
||||
//if (base[j] >= 2 && Ix2[j][base[j] - 1] - Ix2[j][0] >= 2* base.Ix2_max[j] - 2) answer = false;
|
||||
|
||||
//if (is_a_min_Ix2_max_busy && is_a_plus_Ix2_max_busy) return(false);
|
||||
|
||||
bool higher_string_on_zero = false;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
// The following line puts answer to true if there is at least one higher string with zero Ix2
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] > 2) /*&& !(chain.Str_L[j] % 2)*/)
|
||||
higher_string_on_zero = true;
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;
|
||||
// NOTE: if base[j] == 0, Zero_at_level[j] remains false.
|
||||
}
|
||||
|
||||
bool symmetric_state = (*this).Check_Symmetry();
|
||||
|
||||
bool string_coincidence = false;
|
||||
// Checks that we have strings of equal length modulo 2 and same parity with Ix2 == 0, so equal rapidities, and inadmissibility
|
||||
for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
|
||||
for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
|
||||
if (Zero_at_level[j1] && Zero_at_level[j2] && (!((chain.Str_L[j1] + chain.Str_L[j2])%2)))
|
||||
string_coincidence = true;
|
||||
}
|
||||
|
||||
//bool onep_onem_on_zero = false;
|
||||
//if (option == 'm' || option == 'p') { // for Smin, we also exclude symmetric states with 1+ and 1- strings on zero
|
||||
//if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
|
||||
//}
|
||||
|
||||
//cout << min_Ix2_max_busy << "\t" << symmetric_state << "\t" << higher_string_on_zero << "\t" << string_coincidence << "\t" << onep_onem_on_zero << endl;
|
||||
|
||||
//answer = !((symmetric_state && (higher_string_on_zero || string_coincidence || onep_onem_on_zero)));
|
||||
answer = !(symmetric_state && (higher_string_on_zero || string_coincidence));
|
||||
|
||||
// Explicitly exclude state with min_Ix2_max_busy && iK == 0
|
||||
//Compute_Momentum();
|
||||
//answer = !((min_Ix2_max_busy && iK == 0) || (symmetric_state && (higher_string_on_zero || string_coincidence || onep_onem_on_zero)));
|
||||
|
||||
// Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;
|
||||
|
||||
if (!answer) {
|
||||
E = 0.0;
|
||||
K = 0.0;
|
||||
conv = 0;
|
||||
iter = 0;
|
||||
iter_Newton = 0;
|
||||
lnnorm = -100.0;
|
||||
}
|
||||
|
||||
return(answer); // answer == true: nothing wrong with this Ix2_config
|
||||
}
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_BE (int j, int alpha)
|
||||
{
|
||||
// Fills in the BE members with the value of the Bethe equations.
|
||||
|
||||
tanlambda[j][alpha] = tan(lambda[j][alpha]);
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) {
|
||||
sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta])
|
||||
* chain.ta_n_anis_over_2[2]))
|
||||
+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
|
||||
+ PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0))
|
||||
* floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = 2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
+ PI * floor(0.5 + lambda[j][alpha]/PI))
|
||||
- (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
}
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_BE ()
|
||||
{
|
||||
// Fills in the BE members with the value of the Bethe equations.
|
||||
|
||||
(*this).Compute_tanlambda();
|
||||
|
||||
DP sumtheta = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) {
|
||||
sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta])
|
||||
* chain.ta_n_anis_over_2[2]))
|
||||
+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
|
||||
+ PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0))
|
||||
* floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
BE[j][alpha] = 2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
+ PI * floor(0.5 + lambda[j][alpha]/PI))
|
||||
- (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
|
||||
}
|
||||
}
|
||||
|
||||
DP XXZ_gpd_Bethe_State::Iterate_BAE (int j, int alpha)
|
||||
{
|
||||
// Returns a new iteration value for lambda[j][alpha] given tanlambda[][] and BE[][]
|
||||
// Assumes that tanlambda[][] and BE[][] have been computed.
|
||||
|
||||
DP arg0 = 0.5 * (2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
+ PI * floor(0.5 + lambda[j][alpha]/PI)) - BE[j][alpha]);
|
||||
DP arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(
|
||||
arg0
|
||||
//0.5 *
|
||||
//(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
|
||||
//(2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
// + PI * floor(0.5 + lambda[j][alpha]/PI)) - BE[j][alpha])
|
||||
);
|
||||
|
||||
return(atan(arg)
|
||||
//+ PI * floor(0.5 + arg0)
|
||||
//0.5 * (Ix2[j][alpha] + sumtheta/PI)/(chain.Nsites)
|
||||
+ PI * floor(0.5 + arg0/PI)
|
||||
);
|
||||
|
||||
}
|
||||
/*
|
||||
void XXZ_gpd_Bethe_State::Iterate_BAE ()
|
||||
{
|
||||
// Recalculates the rapidities by iterating Bethe equations
|
||||
|
||||
Lambda New_lambda(chain, base);
|
||||
DP sumtheta = 0.0;
|
||||
DP arg = 0.0;
|
||||
|
||||
// First, compute the tan of rapidities:
|
||||
(*this).Compute_tanlambda();
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
sumtheta += atan((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta])
|
||||
* chain.ta_n_anis_over_2[2]))
|
||||
+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
|
||||
else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
|
||||
+ PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0))
|
||||
* floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan((PI * 0.5 * Ix2[j][alpha] + 0.5 * sumtheta)/chain.Nsites);
|
||||
|
||||
New_lambda[j][alpha] = atan(arg) + PI * floor(0.5 + (0.5 * Ix2[j][alpha] + 0.5 * sumtheta/PI)/(chain.Nsites));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DP New_diffsq = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
//New_diffsq += pow(tan(New_lambda[j][alpha]) - tanlambda[j][alpha], 2.0);
|
||||
New_diffsq += pow(New_lambda[j][alpha] - lambda[j][alpha], 2.0);
|
||||
lambda[j][alpha] = 1.0 * New_lambda[j][alpha] + 0.0 * lambda[j][alpha];
|
||||
}
|
||||
}
|
||||
|
||||
diffsq = New_diffsq;
|
||||
iter++;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
void XXZ_gpd_Bethe_State::Iterate_BAE_Newton ()
|
||||
{
|
||||
// does one step of a Newton method on the rapidities...
|
||||
|
||||
Vect_DP RHSBAE (0.0, base.Nraptot); // contains RHS of BAEs
|
||||
Vect_CX dlambda (0.0, base.Nraptot); // contains delta lambda computed from Newton's method
|
||||
SQMat_CX Gaudin (0.0, base.Nraptot);
|
||||
Vect_INT indx (base.Nraptot);
|
||||
DP sumtheta = 0.0;
|
||||
DP arg = 0.0;
|
||||
DP fn_arg = 0.0;
|
||||
DP olddiffsq = diffsq;
|
||||
|
||||
// Compute the RHS of the BAEs:
|
||||
|
||||
int index = 0;
|
||||
|
||||
(*this).Compute_tanlambda();
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
|
||||
sumtheta = 0.0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta)
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) {
|
||||
sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta])
|
||||
* chain.ta_n_anis_over_2[2]))
|
||||
+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]),
|
||||
chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
|
||||
+ PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0))
|
||||
* floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
|
||||
}
|
||||
sumtheta *= 2.0;
|
||||
|
||||
RHSBAE[index] = chain.Nsites * 2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]])
|
||||
+ PI * floor(0.5 + lambda[j][alpha]/PI))
|
||||
// )
|
||||
- sumtheta - PI*Ix2[j][alpha];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
(*this).Build_Reduced_Gaudin_Matrix (Gaudin);
|
||||
|
||||
for (int i = 0; i < base.Nraptot; ++i) dlambda[i] = - RHSBAE[i];
|
||||
|
||||
DP d;
|
||||
ludcmp_CX (Gaudin, indx, d);
|
||||
lubksb_CX (Gaudin, indx, dlambda);
|
||||
|
||||
diffsq = 0.0;
|
||||
// for (int i = 0; i < base.Nraptot; ++i) diffsq += norm(dlambda[i]);
|
||||
int ctr = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
diffsq += norm(tan(lambda[j][alpha] + dlambda[ctr]) - tanlambda[j][alpha]);
|
||||
// cout << "lambda = " << lambda[j][alpha] << "\tdlambda = " << dlambda[ctr] << endl;
|
||||
ctr++;
|
||||
}
|
||||
}
|
||||
|
||||
// if we've converged, calculate the norm here, since the work has been done...
|
||||
|
||||
if (diffsq < chain.prec) {
|
||||
lnnorm = 0.0;
|
||||
for (int j = 0; j < base.Nraptot; j++) lnnorm += log(abs(Gaudin[j][j]));
|
||||
}
|
||||
|
||||
index = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
lambda[j][alpha] += real(dlambda[index]);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
iter_Newton++;
|
||||
|
||||
// cout << "iter_N = " << iter_Newton << "\t" << diffsq << endl;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
bool XXZ_gpd_Bethe_State::Check_Rapidities()
|
||||
{
|
||||
bool nonan = true;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) if (nonan) nonan = ((!is_nan(lambda[j][alpha]))
|
||||
//&& (lambda[j][alpha] > -0.5*PI*chain.Str_L[j])
|
||||
//&& (lambda[j][alpha] <= 0.5*PI*chain.Str_L[j])
|
||||
);
|
||||
|
||||
bool all_within_pi_interval = true;
|
||||
DP min_lambda = 10.0;
|
||||
DP max_lambda = -10.0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
if (lambda[j][alpha] < min_lambda) min_lambda = lambda[j][alpha];
|
||||
if (lambda[j][alpha] > max_lambda) max_lambda = lambda[j][alpha];
|
||||
}
|
||||
|
||||
//all_within_pi_interval = (fabs(max_lambda - min_lambda) < PI - 0.0 * 1.0e-12);
|
||||
// Use pi interval, but centered on 0:
|
||||
all_within_pi_interval = max_lambda < 0.5* PI + 1.0e-8 && min_lambda > -0.5* PI - 1.0e-8;
|
||||
//nonan *= all_within_pi_interval;
|
||||
|
||||
return nonan;
|
||||
}
|
||||
|
||||
DP XXZ_gpd_Bethe_State::String_delta ()
|
||||
{
|
||||
// Computes the sum of absolute value of \delta^{a, a+1} in string hypothesis, for a given bethe eigenstate
|
||||
|
||||
DP delta = 0.0;
|
||||
|
||||
int occupied_strings = 0;
|
||||
for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
|
||||
|
||||
//if ((*this).conv == 0) delta = 1.0;
|
||||
|
||||
if (occupied_strings == 0) delta = 0.0;
|
||||
|
||||
else {
|
||||
|
||||
Vect_DP ln_deltadiff(0.0, 1000); // contains ln |delta^{a, a+1}|
|
||||
Vect_DP deltadiff(0.0, 1000); // contains |delta^{a, a+1}|
|
||||
|
||||
complex<DP> log_BAE_reg = 0.0;
|
||||
|
||||
for (int j = 0; j < (*this).chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < (*this).base[j]; ++alpha) {
|
||||
|
||||
ln_deltadiff = 0.0;
|
||||
|
||||
for (int a = 1; a <= (*this).chain.Str_L[j]; ++a) {
|
||||
|
||||
if ((*this).chain.Str_L[j] > 1) { // else the BAE are already 1
|
||||
|
||||
log_BAE_reg = DP((*this).chain.Nsites) * log(sin((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis
|
||||
* ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0))
|
||||
/sin((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int k = 0; k < (*this).chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < (*this).base[k]; ++beta)
|
||||
for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
|
||||
if ((j != k) || (alpha != beta) || (a != b - 1))
|
||||
|
||||
log_BAE_reg += log(sin(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a ))
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ))
|
||||
- II * (*this).chain.anis));
|
||||
|
||||
if ((j != k) || (alpha != beta) || (a != b + 1))
|
||||
|
||||
log_BAE_reg -= log(sin(((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a ))
|
||||
- ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b ))
|
||||
+ II * (*this).chain.anis));
|
||||
}
|
||||
|
||||
// The regular LHS of BAE is now defined. Now sum up the deltas...
|
||||
|
||||
if (a == 1) ln_deltadiff[0] = -real(log_BAE_reg);
|
||||
|
||||
else if (a < (*this).chain.Str_L[j]) ln_deltadiff[a - 1] = ln_deltadiff[a-2] - real(log_BAE_reg);
|
||||
|
||||
else if (a == (*this).chain.Str_L[j]) ln_deltadiff[a-1] = real(log_BAE_reg);
|
||||
|
||||
} // if ((*this).chain.Str_L[j] > 1)
|
||||
|
||||
} // for (int a = 1; ...
|
||||
|
||||
for (int a = 0; a < (*this).chain.Str_L[j]; ++a) {
|
||||
deltadiff[a] = ln_deltadiff[a] != 0.0 ? exp(ln_deltadiff[a]) : 0.0;
|
||||
delta += fabs(deltadiff[a]);
|
||||
}
|
||||
|
||||
} // alpha sum
|
||||
} // j sum
|
||||
|
||||
if (is_nan(delta)) delta = 1.0; // sentinel
|
||||
|
||||
} // else
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
void XXZ_gpd_Bethe_State::Compute_Energy ()
|
||||
{
|
||||
DP sum = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum += sinh(chain.Str_L[j] * chain.anis) / (cos(2.0 * lambda[j][alpha]) - cosh(chain.Str_L[j] * chain.anis));
|
||||
}
|
||||
}
|
||||
|
||||
sum *= chain.J * sinh(chain.anis);
|
||||
|
||||
E = sum;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
void XXZ_gpd_Bethe_State::Compute_Momentum ()
|
||||
{
|
||||
int sum_Ix2 = 0;
|
||||
DP sum_M = 0.0;
|
||||
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
sum_M += base[j];
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
sum_Ix2 += Ix2[j][alpha];
|
||||
}
|
||||
}
|
||||
|
||||
iK = (chain.Nsites/2) * int(sum_M) - (sum_Ix2/2);
|
||||
|
||||
while (iK >= chain.Nsites) iK -= chain.Nsites;
|
||||
while (iK < 0) iK += chain.Nsites;
|
||||
|
||||
K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
|
||||
|
||||
while (K >= 2.0*PI) K -= 2.0*PI;
|
||||
while (K < 0.0) K += 2.0*PI;
|
||||
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
void XXZ_gpd_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
|
||||
{
|
||||
|
||||
if (Gaudin_Red.size() != base.Nraptot) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
|
||||
|
||||
int index_jalpha;
|
||||
int index_kbeta;
|
||||
|
||||
DP sum_hbar_XXZ = 0.0;
|
||||
|
||||
DP sinhetasq = pow(sinh(chain.anis), 2.0);
|
||||
|
||||
(*this).Compute_sinlambda();
|
||||
(*this).Compute_coslambda();
|
||||
|
||||
index_jalpha = 0;
|
||||
for (int j = 0; j < chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < base[j]; ++alpha) {
|
||||
index_kbeta = 0;
|
||||
for (int k = 0; k < chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < base[k]; ++beta) {
|
||||
|
||||
if ((j == k) && (alpha == beta)) {
|
||||
|
||||
sum_hbar_XXZ = 0.0;
|
||||
|
||||
for (int kp = 0; kp < chain.Nstrings; ++kp) {
|
||||
for (int betap = 0; betap < base[kp]; ++betap) {
|
||||
if (!((j == kp) && (alpha == betap)))
|
||||
sum_hbar_XXZ
|
||||
+= ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp],
|
||||
chain.si_n_anis_over_2);
|
||||
}
|
||||
}
|
||||
|
||||
Gaudin_Red[index_jalpha][index_kbeta]
|
||||
= complex<DP> ( chain.Nsites * hbar_XXZ_gpd (lambda[j][alpha], chain.Str_L[j], chain.si_n_anis_over_2) - sum_hbar_XXZ);
|
||||
}
|
||||
|
||||
else {
|
||||
if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1))
|
||||
Gaudin_Red[index_jalpha][index_kbeta] =
|
||||
complex<DP> (chain.si_n_anis_over_2[4]/(pow(sinlambda[j][alpha] * coslambda[k][beta]
|
||||
- coslambda[j][alpha] * sinlambda[k][beta], 2.0) + sinhetasq));
|
||||
else
|
||||
Gaudin_Red[index_jalpha][index_kbeta] = complex<DP> (ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j],
|
||||
chain.Str_L[k], chain.si_n_anis_over_2));
|
||||
}
|
||||
index_kbeta++;
|
||||
}
|
||||
}
|
||||
index_jalpha++;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// ****************************************************************************************************
|
||||
|
||||
// non-member functions
|
||||
|
||||
inline DP fbar_XXZ_gpd (DP tanlambda, DP tanhnetaover2)
|
||||
{
|
||||
return (2.0 * atan(tanlambda/tanhnetaover2));
|
||||
}
|
||||
|
||||
DP Theta_XXZ_gpd (DP tanlambda, int nj, int nk, DP* tanhnetaover2)
|
||||
{
|
||||
DP result;
|
||||
|
||||
if ((nj == 1) && (nk == 1)) result = fbar_XXZ_gpd(tanlambda, tanhnetaover2[2]);
|
||||
|
||||
else {
|
||||
|
||||
result = (nj == nk) ? 0.0 : fbar_XXZ_gpd(tanlambda, tanhnetaover2[fabs(nj - nk)]);
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * fbar_XXZ_gpd(tanlambda, tanhnetaover2[fabs(nj - nk) + 2*a]);
|
||||
|
||||
result += fbar_XXZ_gpd(tanlambda, tanhnetaover2[nj + nk]);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
DP hbar_XXZ_gpd (DP lambda, int n, DP* si_n_anis_over_2)
|
||||
{
|
||||
return (si_n_anis_over_2[2*n]/(pow(sin(lambda), 2.0) + pow(si_n_anis_over_2[n], 2.0)));
|
||||
}
|
||||
|
||||
DP ddlambda_Theta_XXZ_gpd (DP lambda, int nj, int nk, DP* si_n_anis_over_2)
|
||||
{
|
||||
DP result = (nj == nk) ? 0.0 : hbar_XXZ_gpd(lambda, fabs(nj - nk), si_n_anis_over_2);
|
||||
|
||||
for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * hbar_XXZ_gpd(lambda, fabs(nj - nk) + 2*a, si_n_anis_over_2);
|
||||
|
||||
result += hbar_XXZ_gpd(lambda, nj + nk, si_n_anis_over_2);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
XXZ_gpd_Bethe_State Add_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState)
|
||||
{
|
||||
if (2*RefState.base.Mdown == RefState.chain.Nsites)
|
||||
JSCerror("Trying to add a down spin to a zero-magnetized chain in Add_Particle_at_Center.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] + 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXZ_gpd_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Add a quantum number in middle (explicitly: to right of index M[0]/2)
|
||||
// and shift quantum numbers by half-integer away from added one:
|
||||
ReturnState.Ix2[0][RefState.base.Nrap[0]/2] = RefState.Ix2[0][RefState.base.Nrap[0]/2] - 1;
|
||||
for (int i = 0; i < RefState.base.Nrap[0] + 1; ++i)
|
||||
ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] = RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
|
||||
XXZ_gpd_Bethe_State Remove_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState)
|
||||
{
|
||||
if (RefState.base.Nrap[0] == 0)
|
||||
JSCerror("Trying to remove a down spin in an empty Nrap[0] state.");
|
||||
|
||||
Vect<int> newM = RefState.base.Nrap;
|
||||
newM[0] = newM[0] - 1;
|
||||
|
||||
Heis_Base newBase (RefState.chain, newM);
|
||||
|
||||
XXZ_gpd_Bethe_State ReturnState (RefState.chain, newBase);
|
||||
|
||||
for (int il = 1; il < RefState.chain.Nstrings; ++il)
|
||||
for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha)
|
||||
ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
|
||||
|
||||
// Remove midmost and shift quantum numbers by half-integer towards removed one:
|
||||
for (int i = 0; i < RefState.base.Nrap[0]-1; ++i)
|
||||
ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
|
||||
|
||||
return(ReturnState);
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,253 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Overlap (XXX_Bethe_State& A, XXX_Bethe_State& B)
|
||||
{
|
||||
// This function returns the overlap of states A and B.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// IMPORTANT ASSUMPTIONS:
|
||||
// - State B is an eigenstate of the model on which the overlap measure is defined
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) return(complex<DP>(-300.0)); // overlap vanishes
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
//complex<DP> ln_prod1 = 0.0;
|
||||
//complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
/*
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
*/
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
|
||||
|
||||
// ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
// ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
|
||||
|
||||
// Now proceed to build the Hm2P matrix
|
||||
|
||||
SQMat_CX Hm2P(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
//complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
//complex<DP> two_over_A_lambda_sq_plus_1over2sq;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
//two_over_A_lambda_sq_plus_1over2sq = 2.0/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
|
||||
// (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
//Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (B.chain.Nsites));
|
||||
Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (A.chain.Nsites)); // careful !
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
|
||||
//- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
|
||||
;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
//sum2 = 0.0;
|
||||
|
||||
//for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1))); // include all string contributions F_B_0 in this term
|
||||
|
||||
//Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq);
|
||||
Hm2P[index_a][index_b] = prod_num * sum1;
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
//cout << "Matrix: " << endl;
|
||||
//Hm2P.Print();
|
||||
|
||||
complex<DP> det = lndet_LU_CX_dstry(Hm2P);
|
||||
|
||||
/*
|
||||
complex<DP> ln_form_factor_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
// + 2.0 * real(lndet_LU_CX_dstry(Hm2P))
|
||||
+ 2.0 * det
|
||||
- A.lnnorm - B.lnnorm;
|
||||
|
||||
//cout << "ln_SZ: " << endl << ln_prod1 << "\t" << -ln_prod2 << "\t" << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
|
||||
// << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
|
||||
|
||||
return(ln_form_factor_sq);
|
||||
*/
|
||||
complex<DP> ln_overlap = 0.5 * (-ln_prod3 + ln_prod4) + det - 0.5 * (A.lnnorm + B.lnnorm);
|
||||
|
||||
cout << "ln_overlap: " << endl << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
|
||||
<< "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
|
||||
|
||||
return(ln_overlap);
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,239 @@
|
|||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Smin_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^- operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states are compatible
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Smin matrix element.");
|
||||
|
||||
// Check that A and B are Mdown-compatible:
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown + 1) JSCerror("Incompatible Mdown between the two states in Smin matrix element!");
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
complex<DP> ln_FB0, ln_FG0, ln_FG2;
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
//re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
//im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
ln_FB0 = ln_Fn_F(B, j, alpha, 0);
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_FB0);
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_FB0);
|
||||
//re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
//im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
ln_FG0 = ln_Fn_G(A, B, j, alpha, 0);
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_FG0);
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_FG0);
|
||||
//re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
//im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
ln_FG2 = ln_Fn_G(A, B, j, alpha, 2);
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_FG2);
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_FG2);
|
||||
}
|
||||
}
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);
|
||||
|
||||
// ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
// ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
|
||||
|
||||
// Now proceed to build the Hm matrix
|
||||
|
||||
SQMat_CX Hm(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> one_over_A_lambda_sq_plus_1over2sq;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
one_over_A_lambda_sq_plus_1over2sq = 1.0/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
|
||||
(A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] + II * 0.5) /(B.lambda[k][beta] - II * 0.5), complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
|
||||
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
/*
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
*/
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)));
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm[index_a][index_b] = prod_num * sum1;
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements Hm[a][M]
|
||||
|
||||
Hm[index_a][B.base.Mdown] = one_over_A_lambda_sq_plus_1over2sq;
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
+ 2.0 * real(lndet_LU_CX_dstry(Hm)) - A.lnnorm - B.lnnorm;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,328 @@
|
|||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
int arg = 0;
|
||||
int absarg = 0;
|
||||
int par_comb_1, par_comb_2;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
|
||||
par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
|
||||
par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
|
||||
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b))) {
|
||||
|
||||
arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
absarg = abs(arg);
|
||||
/*
|
||||
prod_temp *= 0.5 * //done later...
|
||||
((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
+ B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
|
||||
*/
|
||||
|
||||
prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
|
||||
}
|
||||
|
||||
if (counter++ > 100) { // we do at most 100 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXZ_Bethe_State& A, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
int arg = 0;
|
||||
int absarg = 0;
|
||||
int par_comb_1, par_comb_2;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
|
||||
par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
|
||||
par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
|
||||
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
absarg = abs(arg);
|
||||
/*
|
||||
prod_temp *= 0.5 * //done later...
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) );
|
||||
*/
|
||||
prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
|
||||
|
||||
if (counter++ > 100) { // we do at most 100 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXZ_Bethe_State& A, int j, int alpha, int a, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
int absarg1 = abs(arg1);
|
||||
int arg2 = arg1 + 2;
|
||||
int absarg2 = abs(arg2);
|
||||
|
||||
return(4.0/(
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
|
||||
*
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXZ_Bethe_State& A, int j, int alpha, int a, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
+ 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k])))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Smin_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^- operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states are compatible
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXZ_Chains in Smin matrix element.");
|
||||
|
||||
// Check that A and B are Mdown-compatible:
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown + 1) {
|
||||
cout << "A.base.Mdown = " << A.base.Mdown << "\tB.base.Mdown = " << B.base.Mdown << endl;
|
||||
cout << "A: " << A << endl << "B: " << B << endl;
|
||||
JSCerror("Incompatible Mdown between the two states in Smin matrix element!");
|
||||
}
|
||||
|
||||
// Compute the sinh and cosh of rapidities
|
||||
|
||||
A.Compute_sinhlambda();
|
||||
A.Compute_coshlambda();
|
||||
B.Compute_sinhlambda();
|
||||
B.Compute_coshlambda();
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[i]))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
DP logabssinzeta = log(abs(sin(A.chain.anis)));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1); // assume only one-strings here
|
||||
|
||||
ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
|
||||
|
||||
// Now proceed to build the Hm matrix
|
||||
|
||||
SQMat_CX Hm(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
|
||||
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
one_over_A_sinhlambda_sq_plus_sinzetaover2sq = 1.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
* (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
+ pow(sin(0.5*A.chain.anis), 2.0));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
|
||||
|
||||
Prod_powerN = pow( B.chain.par[k] == 1 ?
|
||||
(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
:
|
||||
(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
, complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
|
||||
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
/*
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
*/
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinzeta);
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm[index_a][index_b] = prod_num * sum1;
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements Hm[a][M]
|
||||
|
||||
Hm[index_a][B.base.Mdown] = one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
+ 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinzeta - A.lnnorm - B.lnnorm;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,303 @@
|
|||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
/*
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(-II * sin(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.eta * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))));
|
||||
*/
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b))) {
|
||||
|
||||
// arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// absarg = abs(arg);
|
||||
|
||||
prod_temp *= -II * (B.sinlambda[j][alpha] * B.coslambda[k][beta] - B.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(B.coslambda[j][alpha] * B.coslambda[k][beta] + B.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (counter++ > 10) { // we do at most 10 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
// return(ans);
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
/*
|
||||
prod_temp *= -II * sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.eta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
*/
|
||||
|
||||
// arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// absarg = abs(arg);
|
||||
|
||||
prod_temp *= -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
|
||||
if (counter++ > 25) { // we do at most 25 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
}}}
|
||||
|
||||
// return(ans);
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXZ_gpd_Bethe_State& A, int j, int alpha, int a, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
/*
|
||||
return(-1.0/(sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)))));
|
||||
*/
|
||||
|
||||
// int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// int absarg1 = abs(arg1);
|
||||
// int arg2 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b - 1);
|
||||
// int arg2 = arg1 + 2;
|
||||
// int absarg2 = abs(arg2);
|
||||
|
||||
return(1.0/(( -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))) *
|
||||
(-II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))))));
|
||||
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXZ_gpd_Bethe_State& A, int j, int alpha, int a, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
/*
|
||||
complex<DP> ans = -II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))));
|
||||
|
||||
return (ans * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
*/
|
||||
return (-II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Smin_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^- operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXZ_gpd_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXZ_gpd_Chains in Smin matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown + 1) JSCerror("Incompatible Mdown between the two states in Smin matrix element!");
|
||||
|
||||
// Compute the sin and cos of rapidities
|
||||
|
||||
A.Compute_sinlambda();
|
||||
A.Compute_coslambda();
|
||||
B.Compute_sinlambda();
|
||||
B.Compute_coslambda();
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(sin(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(sin(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(sin(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
// one_over_A_sinlambda_sq_plus_sinhetaover2sq[j][alpha] = 1.0/(pow(A.sinlambda[j][alpha], 2.0) + pow(sinh(0.5*A.chain.anis), 2.0));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
DP logabssinheta = log(abs(sinh(A.chain.anis)));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);
|
||||
|
||||
ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
ln_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis)));
|
||||
|
||||
// Now proceed to build the Hm matrix
|
||||
|
||||
SQMat_CX Hm(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> one_over_A_sinlambda_sq_plus_sinhetaover2sq = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
one_over_A_sinlambda_sq_plus_sinhetaover2sq = -1.0/((sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
|
||||
+ 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a))) *
|
||||
(sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
|
||||
+ 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)))
|
||||
+ pow(sinh(0.5*A.chain.anis), 2.0));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
|
||||
|
||||
Prod_powerN = pow((B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1]),
|
||||
complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
/*
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
*/
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinheta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinheta);
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm[index_a][index_b] = prod_num * sum1;
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements Hm[a][M]
|
||||
|
||||
Hm[index_a][B.base.Mdown] = one_over_A_sinlambda_sq_plus_sinhetaover2sq;
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
+ 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinheta - A.lnnorm - B.lnnorm;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,307 @@
|
|||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
inline complex<DP> phi(complex<DP> x){return x;}
|
||||
inline complex<DP> a(complex<DP> x){return 1;}
|
||||
inline complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta){ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
|
||||
inline complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
|
||||
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
|
||||
complex<DP> ln_Smm_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
|
||||
{
|
||||
const DP Zero_Center_Thres=1.0e-5;
|
||||
const DP real_dev=1.0e-14;
|
||||
const DP Diff_ME_Thres=1.e-6;
|
||||
|
||||
//clock_t start_time_local = clock();
|
||||
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
// A is the reference state.
|
||||
|
||||
// Check that the two states refer to the same XXX_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Smm matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown + 2) JSCerror("Incompatible Mdown between the two states in Smm matrix element!");
|
||||
|
||||
//if(B.String_delta()> HEIS_deltaprec) return(complex<DP>(-300.0)); // DEPRECATED in ++T_9
|
||||
|
||||
|
||||
//if (B.type_id > 999999LL) return(complex<DP>(-300.0));
|
||||
|
||||
// Some convenient arrays
|
||||
complex<DP> eta=-II;
|
||||
complex<DP> ln_prod = complex<DP>(0.0,0.0);
|
||||
complex<DP> result=-300;
|
||||
complex<DP> prev_result=-300;
|
||||
|
||||
XXX_Bethe_State B_origin; B_origin=B;
|
||||
bool zero_string=false;
|
||||
for (int j = 0; j < B_origin.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < B_origin.base.Nrap[j]; ++alpha)
|
||||
if(abs(B_origin.lambda[j][alpha])<Zero_Center_Thres) zero_string=true;
|
||||
|
||||
// Some convenient arrays
|
||||
bool real_dev_conv=false;
|
||||
int dev=-1;
|
||||
while(!real_dev_conv){
|
||||
real_dev_conv=true;
|
||||
|
||||
dev++;
|
||||
//add a delta to the origin of the centered strings
|
||||
if(zero_string){
|
||||
real_dev_conv=false;
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha)
|
||||
if(abs(B_origin.lambda[j][alpha])<Zero_Center_Thres)
|
||||
B.lambda[j][alpha]=real_dev*pow(10.0,dev);
|
||||
}
|
||||
|
||||
prev_result=result;
|
||||
|
||||
|
||||
|
||||
result=log(B.chain.Nsites*1.0);
|
||||
|
||||
int sizeA=0;
|
||||
int sizeB=0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
sizeA+=A.base.Nrap[i]*A.chain.Str_L[i];
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
sizeB+=B.base.Nrap[i]*B.chain.Str_L[i];
|
||||
|
||||
complex<DP>* mu = new complex<DP>[sizeA];
|
||||
complex<DP>* lam = new complex<DP>[sizeB];
|
||||
int index=0;
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
{
|
||||
mu[index]=(A.lambda[i][alpha] + 0.5 * -eta * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
index++;
|
||||
}
|
||||
|
||||
index=0;
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
{
|
||||
lam[index]=(B.lambda[i][alpha] + 0.5 * -eta * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
index++;
|
||||
}
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
result += 2.0*real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4) - A.lnnorm - B.lnnorm;
|
||||
// Define the F ones earlier...
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
complex<DP> Prod_powerN;
|
||||
|
||||
//mu is the ground state!
|
||||
//A -> mu, B -> lam
|
||||
SQMat_CX H(0.0, A.base.Mdown);
|
||||
index_a = 0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
complex<DP> Da;
|
||||
complex<DP> Ca;
|
||||
Da=eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
|
||||
Ca=eta*((mu[index_a]-eta*0.5)+(mu[index_a]+eta*0.5))/pow(((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5)),2.0);
|
||||
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
|
||||
complex<DP> prodplus= complex<DP>(1.0,0.0);
|
||||
complex<DP> prodminus= complex<DP>(1.0,0.0);
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
|
||||
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
|
||||
|
||||
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
|
||||
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] - eta*0.5) /(B.lambda[k][beta] + eta*0.5), complex<DP> (B.chain.Nsites));
|
||||
H[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
// */{
|
||||
|
||||
if (b > 1){
|
||||
H[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)*exp(ln_Fn_G(A,B,k,beta,b-1))*exp(-real(ln_Fn_F(B, k, beta, b - 1)));//.../ prod_l!=k | phi(lam[l]-lam[k]) |
|
||||
}
|
||||
else if (b == 1) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
complex<DP> sum1 = complex<DP>(0.0,0.0);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1]
|
||||
- ln_FunctionF[0] - ln_FunctionF[1]);//sum term when i=0
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); //sum term when i=n
|
||||
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) {
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
}
|
||||
|
||||
H[index_a][index_b] = eta * exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum1 * exp( - real(ln_Fn_F(B, k, beta, b - 1))); //the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements H[a][M] & H[a][M-1]
|
||||
H[index_a][B.base.Mdown]=Da;
|
||||
H[index_a][B.base.Mdown+1]=Ca;
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> logF=lndet_LU_CX_dstry(H);
|
||||
result+=2.0*real(logF);
|
||||
result+=log(2.0)-log((A.chain.Nsites-A.base.Mdown*2+3.0)*((A.chain.Nsites-A.base.Mdown*2+4.0)));
|
||||
if (!(real_dev_conv) && abs(exp(result)-exp(prev_result))<abs( Diff_ME_Thres*exp(result)))
|
||||
real_dev_conv=true;
|
||||
|
||||
if (!(real_dev_conv) && dev >20){
|
||||
result=-300;
|
||||
real_dev_conv=true;
|
||||
}
|
||||
|
||||
delete[] mu;
|
||||
delete[] lam;
|
||||
|
||||
}
|
||||
//return(result);
|
||||
return(0.5 * result); // Return ME, not MEsq
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,247 @@
|
|||
/**********************************************************
|
||||
|
||||
This software is part of J.-S. Caux's ABACUS++ library.
|
||||
|
||||
Copyright (c)
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
***********************************************************/
|
||||
|
||||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Sz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXX_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Sz matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
|
||||
|
||||
//if (A.iK == B.iK && (A.label != B.label))
|
||||
if (A.iK == B.iK && (A.label.compare(B.label) != 0))
|
||||
return(-300.0); // matrix element identically vanishes
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
|
||||
|
||||
// ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
// ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
|
||||
|
||||
// Now proceed to build the Hm2P matrix
|
||||
|
||||
SQMat_CX Hm2P(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> two_over_A_lambda_sq_plus_1over2sq;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
two_over_A_lambda_sq_plus_1over2sq = 2.0/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
|
||||
(A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
|
||||
- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1))); // include all string contributions F_B_0 in this term
|
||||
|
||||
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq);
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
//cout << "Matrix: " << endl;
|
||||
//Hm2P.Print();
|
||||
|
||||
DP det = real(lndet_LU_CX_dstry(Hm2P));
|
||||
|
||||
complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
// + 2.0 * real(lndet_LU_CX_dstry(Hm2P))
|
||||
+ 2.0 * det
|
||||
- A.lnnorm - B.lnnorm;
|
||||
|
||||
//cout << "ln_Sz: " << endl << ln_prod1 << "\t" << -ln_prod2 << "\t" << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det
|
||||
// << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,563 @@
|
|||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
int arg = 0;
|
||||
int absarg = 0;
|
||||
int par_comb_1, par_comb_2;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
|
||||
par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
|
||||
par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
|
||||
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b))) {
|
||||
|
||||
arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
absarg = abs(arg);
|
||||
/*
|
||||
prod_temp *= 0.5 *
|
||||
((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg)
|
||||
* B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
|
||||
+ B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
|
||||
*/
|
||||
prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (B.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_2)
|
||||
+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * par_comb_1 + B.chain.co_n_anis_over_2[absarg] * par_comb_2));
|
||||
|
||||
}
|
||||
|
||||
if (counter++ > 100) { // we do at most 100 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXZ_Bethe_State& A, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
int arg = 0;
|
||||
int absarg = 0;
|
||||
int par_comb_1, par_comb_2;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
|
||||
par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
|
||||
par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
|
||||
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
absarg = abs(arg);
|
||||
|
||||
/*
|
||||
prod_temp *= 0.5 *
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) );
|
||||
*/
|
||||
prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg] * par_comb_1 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_2)
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * par_comb_1 + A.chain.co_n_anis_over_2[absarg] * par_comb_2));
|
||||
|
||||
if (counter++ > 100) { // we do at most 100 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
}}}
|
||||
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXZ_Bethe_State& A, int j, int alpha, int a, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
int absarg1 = abs(arg1);
|
||||
int arg2 = arg1 + 2;
|
||||
int absarg2 = abs(arg2);
|
||||
|
||||
return(4.0/(
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
|
||||
*
|
||||
((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
- sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
|
||||
+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta])
|
||||
* (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
|
||||
+ A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXZ_Bethe_State& A, int j, int alpha, int a, XXZ_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
+ 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k])))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
|
||||
// Version without phases:
|
||||
complex<DP> ln_Sz_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXZ_Chain
|
||||
|
||||
if (A.chain != B.chain) {
|
||||
JSCerror("Incompatible XXZ_Chains in Sz matrix element.");
|
||||
}
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) {
|
||||
cout << "Bra state: " << endl << A << endl;
|
||||
cout << "Ket state: " << endl << B << endl;
|
||||
cout << A.base.Mdown << "\t" << B.base.Mdown << endl;
|
||||
JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
|
||||
}
|
||||
|
||||
if (A.iK == B.iK && (A.label != B.label))
|
||||
return(-300.0); // matrix element identically vanishes
|
||||
|
||||
// Compute the sinh and cosh of rapidities
|
||||
|
||||
A.Compute_sinhlambda();
|
||||
A.Compute_coshlambda();
|
||||
B.Compute_sinhlambda();
|
||||
B.Compute_coshlambda();
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[i]))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
complex<DP> ln_Fn_F_B_0;
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
ln_Fn_F_B_0 = ln_Fn_F(B, j, alpha, 0);
|
||||
//re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
//im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F_B_0);
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F_B_0);
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
DP logabssinzeta = log(abs(sin(A.chain.anis)));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
|
||||
}
|
||||
|
||||
ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
|
||||
|
||||
// Now proceed to build the Hm2P matrix
|
||||
|
||||
SQMat_CX Hm2P(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> two_over_A_sinhlambda_sq_plus_sinzetaover2sq;
|
||||
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
two_over_A_sinhlambda_sq_plus_sinzetaover2sq = 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
* (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
+ pow(sin(0.5*A.chain.anis), 2.0));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinzeta);
|
||||
|
||||
Prod_powerN = pow( B.chain.par[k] == 1 ?
|
||||
(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
:
|
||||
(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
, complex<DP> (B.chain.Nsites));
|
||||
|
||||
//cout << "Prod_powerN = " << Prod_powerN << "\t" << abs(Prod_powerN) << endl;
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq
|
||||
* exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinzeta);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logabssinzeta);
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinhlambda_sq_plus_sinzetaover2sq);
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
DP re_ln_det = real(lndet_LU_CX_dstry(Hm2P));
|
||||
|
||||
complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
+ 2.0 * /*real(lndet_LU_CX_dstry(Hm2P))*/ re_ln_det - A.lnnorm - B.lnnorm;
|
||||
|
||||
//cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm
|
||||
//<< "\t" << re_ln_det << "\t" << ln_ME_sq << endl;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
// Version with phases:
|
||||
complex<DP> ln_Sz_ME_with_phase (XXZ_Bethe_State& A, XXZ_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXZ_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXZ_Chains in Sz matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) {
|
||||
cout << "Bra state: " << endl << A << endl;
|
||||
cout << "Ket state: " << endl << B << endl;
|
||||
cout << A.base.Mdown << "\t" << B.base.Mdown << endl;
|
||||
JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
|
||||
}
|
||||
|
||||
if (A.iK == B.iK && (A.label != B.label))
|
||||
return(-300.0); // matrix element identically vanishes
|
||||
|
||||
// Compute the sinh and cosh of rapidities
|
||||
|
||||
A.Compute_sinhlambda();
|
||||
A.Compute_coshlambda();
|
||||
B.Compute_sinhlambda();
|
||||
B.Compute_coshlambda();
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(sinh(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[i])));
|
||||
|
||||
complex<DP> shB;
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(shB = sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
|
||||
//ln_prod2 += log(norm(sinh(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)
|
||||
// + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
|
||||
ln_prod2 += log(shB);
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
complex<DP> ln_Fn_F_B_0, ln_Fn_G_0, ln_Fn_G_2;
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
//re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
//im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
ln_Fn_F_B_0 = ln_Fn_F(B, j, alpha, 0);
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F_B_0);
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F_B_0);
|
||||
//re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
//im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
ln_Fn_G_0 = ln_Fn_G(A, B, j, alpha, 0);
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G_0);
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G_0);
|
||||
//re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
//im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
ln_Fn_G_0 = ln_Fn_G(A, B, j, alpha, 2);
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G_2);
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G_2);
|
||||
}
|
||||
}
|
||||
|
||||
DP logsinzeta = log(sin(A.chain.anis));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
|
||||
}
|
||||
|
||||
//ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
|
||||
ln_prod3 -= A.base.Mdown * logsinzeta;
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
//ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
|
||||
ln_prod4 -= B.base.Mdown * logsinzeta;
|
||||
|
||||
// Now proceed to build the Hm2P matrix
|
||||
|
||||
SQMat_CX Hm2P(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> two_over_A_sinhlambda_sq_plus_sinzetaover2sq;
|
||||
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
two_over_A_sinhlambda_sq_plus_sinzetaover2sq = 2.0/((sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
* (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
|
||||
+ 0.25 * II * PI * (1.0 - A.chain.par[j])))
|
||||
+ pow(sin(0.5*A.chain.anis), 2.0));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logsinzeta);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logsinzeta);
|
||||
|
||||
Prod_powerN = pow( B.chain.par[k] == 1 ?
|
||||
(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.sinhlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coshlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
:
|
||||
(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.coshlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.sinhlambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
, complex<DP> (B.chain.Nsites));
|
||||
|
||||
//cout << "Prod_powerN = " << Prod_powerN << "\t" << abs(Prod_powerN) << endl;
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq
|
||||
* exp(II*im_ln_Fn_F_B_0[k][beta] + logsinzeta);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logsinzeta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logsinzeta);
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinhlambda_sq_plus_sinzetaover2sq);
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> ln_det = lndet_LU_CX_dstry(Hm2P);
|
||||
|
||||
complex<DP> ln_ME = log(0.5 * sqrt(A.chain.Nsites)) + ln_prod1 - ln_prod2 - ln_prod3 + ln_prod4 + 2.0 * ln_det - A.lnnorm - B.lnnorm;
|
||||
|
||||
//cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm
|
||||
//<< "\t" << re_ln_det << "\t" << ln_form_factor_sq << endl;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(ln_ME); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,304 @@
|
|||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
namespace JSC {
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
/*
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(-II * sin(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.eta * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))));
|
||||
*/
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b))) {
|
||||
|
||||
// arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// absarg = abs(arg);
|
||||
|
||||
prod_temp *= -II * (B.sinlambda[j][alpha] * B.coslambda[k][beta] - B.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(B.coslambda[j][alpha] * B.coslambda[k][beta] + B.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (counter++ > 10) { // we do at most 10 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
// return(ans);
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
complex<DP> prod_temp = 1.0;
|
||||
int counter = 0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
/*
|
||||
prod_temp *= -II * sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.eta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
*/
|
||||
|
||||
// arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// absarg = abs(arg);
|
||||
|
||||
prod_temp *= -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
|
||||
if (counter++ > 25) { // we do at most 25 products before taking a log
|
||||
ans += log(prod_temp);
|
||||
prod_temp = 1.0;
|
||||
counter = 0;
|
||||
}
|
||||
}}}
|
||||
|
||||
// return(ans);
|
||||
return(ans + log(prod_temp));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXZ_gpd_Bethe_State& A, int j, int alpha, int a, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
/*
|
||||
return(-1.0/(sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* sin(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)))));
|
||||
*/
|
||||
|
||||
// int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
|
||||
// int absarg1 = abs(arg1);
|
||||
// int arg2 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b - 1);
|
||||
// int arg2 = arg1 + 2;
|
||||
// int absarg2 = abs(arg2);
|
||||
|
||||
return(1.0/(( -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))) *
|
||||
(-II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))) +
|
||||
(A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
|
||||
* sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))))));
|
||||
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXZ_gpd_Bethe_State& A, int j, int alpha, int a, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
/*
|
||||
complex<DP> ans = -II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))));
|
||||
|
||||
return (ans * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
*/
|
||||
return (-II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
complex<DP> ln_Sz_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B)
|
||||
{
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXZ_gpd_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXZ_gpd_Chains in Sz matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown) JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
|
||||
|
||||
if (A.iK == B.iK && (A.label != B.label))
|
||||
return(-300.0); // matrix element identically vanishes
|
||||
|
||||
// Compute the sin and cos of rapidities
|
||||
|
||||
A.Compute_sinlambda();
|
||||
A.Compute_coslambda();
|
||||
B.Compute_sinlambda();
|
||||
B.Compute_coslambda();
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(sin(A.lambda[i][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(sin(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(sin(B.lambda[i][alpha] + 0.5 * II * B.chain.anis * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
DP logabssinheta = log(abs(sinh(A.chain.anis)));
|
||||
|
||||
// Define regularized products in prefactors
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a)
|
||||
ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);
|
||||
|
||||
ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis)));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k)
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
|
||||
else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
|
||||
}
|
||||
|
||||
ln_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis)));
|
||||
|
||||
// Now proceed to build the Hm2P matrix
|
||||
|
||||
SQMat_CX Hm2P(0.0, A.base.Mdown);
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
|
||||
complex<DP> sum1 = 0.0;
|
||||
complex<DP> sum2 = 0.0;
|
||||
complex<DP> prod_num = 0.0;
|
||||
complex<DP> Fn_K_0_G_0 = 0.0;
|
||||
complex<DP> Prod_powerN = 0.0;
|
||||
complex<DP> Fn_K_1_G_2 = 0.0;
|
||||
complex<DP> two_over_A_sinlambda_sq_plus_sinhetaover2sq = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
two_over_A_sinlambda_sq_plus_sinhetaover2sq = -2.0/((sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
|
||||
+ 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a))) *
|
||||
(sin(A.lambda[j][alpha] // minus sign: from 1/(sinh^2... to -1/(sin^2...
|
||||
+ 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)))
|
||||
+ pow(sinh(0.5*A.chain.anis), 2.0));
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
|
||||
exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
|
||||
Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
|
||||
exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta] + logabssinheta);
|
||||
|
||||
Prod_powerN = pow((B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] + II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1])
|
||||
/(B.sinlambda[k][beta] * B.chain.co_n_anis_over_2[1] - II * B.coslambda[k][beta] * B.chain.si_n_anis_over_2[1]),
|
||||
complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
|
||||
- two_over_A_sinlambda_sq_plus_sinhetaover2sq * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinheta);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
|
||||
else if (b == B.chain.Str_L[k]) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
sum1 = 0.0;
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
sum2 = 0.0;
|
||||
|
||||
for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum) sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
|
||||
|
||||
prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinheta);
|
||||
|
||||
for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)
|
||||
prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinheta);
|
||||
// include all string contributions F_B_0 in this term
|
||||
|
||||
Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinlambda_sq_plus_sinhetaover2sq);
|
||||
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
|
||||
+ 2.0 * real(lndet_LU_CX_dstry(Hm2P)) - A.lnnorm - B.lnnorm;
|
||||
|
||||
//cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm << "\t"
|
||||
// << lndet_LU_CX(Hm2P) << endl;
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
|
@ -0,0 +1,502 @@
|
|||
#include "JSC.h"
|
||||
|
||||
using namespace JSC;
|
||||
|
||||
|
||||
namespace JSC {
|
||||
inline complex<DP> phi(complex<DP> x){return x;}
|
||||
inline complex<DP> a(complex<DP> x){return 1;}
|
||||
inline complex<DP> b(complex<DP> x,complex<DP> y, complex<DP> eta){ return phi(x-y)/phi(x-y+complex<DP>(0.0,1.0)*eta);}
|
||||
inline complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
|
||||
|
||||
|
||||
inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
|
||||
|
||||
if (!((j == k) && (alpha == beta) && (a == b)))
|
||||
ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
complex<DP> ans = 0.0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(ans);
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_K (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
|
||||
* (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
|
||||
}
|
||||
|
||||
inline complex<DP> Fn_L (XXX_Bethe_State& A, int j, int alpha, int a, XXX_Bethe_State& B, int k, int beta, int b)
|
||||
{
|
||||
return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
|
||||
+ 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5))
|
||||
))
|
||||
* pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
|
||||
}
|
||||
|
||||
|
||||
complex<DP> ln_Szm_p_Smz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
|
||||
{
|
||||
//clock_t start_time_local = clock();
|
||||
//A has to be the ground state!
|
||||
|
||||
// This function returns the natural log of the S^z operator matrix element.
|
||||
// The A and B states can contain strings.
|
||||
|
||||
// Check that the two states refer to the same XXX_Chain
|
||||
|
||||
if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Szm_p_Smz matrix element.");
|
||||
|
||||
// Check that A and B are compatible: same Mdown
|
||||
|
||||
if (A.base.Mdown != B.base.Mdown + 1) JSCerror("Incompatible Mdown between the two states in SzSm_p_SmSz matrix element!");
|
||||
|
||||
//if (B.type_id > 999999LL) return(complex<DP>(-300.0));
|
||||
|
||||
//add a delta to the origin of the centered strings
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
if(abs(A.lambda[i][alpha])<5.55112e-12)A.lambda[i][alpha]=5.55112e-12;
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
if(abs(B.lambda[i][alpha])<5.55112e-5)B.lambda[i][alpha]=5.55112e-5;
|
||||
|
||||
// Some convenient arrays
|
||||
|
||||
complex<DP> i=complex<DP>(0.0,1.0);
|
||||
complex<DP> eta=-i;
|
||||
complex<DP> ln_prod = complex<DP>(0.0,0.0);
|
||||
complex<DP> result;
|
||||
result=log(B.chain.Nsites*1.0/4.0);
|
||||
|
||||
int sizeA=0;
|
||||
int sizeB=0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
sizeA+=A.base.Nrap[i]*A.chain.Str_L[i];
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
sizeB+=B.base.Nrap[i]*B.chain.Str_L[i];
|
||||
|
||||
complex<DP>* mu = new complex<DP>[sizeA];
|
||||
complex<DP>* lam = new complex<DP>[sizeB];
|
||||
int index=0;
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
{
|
||||
// mu[index]=(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
mu[index]=(A.lambda[i][alpha] + 0.5 * -eta * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
index++;
|
||||
}
|
||||
|
||||
index=0;
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
{
|
||||
// lam[index]=(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
lam[index]=(B.lambda[i][alpha] + 0.5 * -eta * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
|
||||
index++;
|
||||
}
|
||||
|
||||
Lambda re_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_F_B_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_0(B.chain, B.base);
|
||||
Lambda re_ln_Fn_G_2(B.chain, B.base);
|
||||
Lambda im_ln_Fn_G_2(B.chain, B.base);
|
||||
|
||||
complex<DP> ln_prod1 = 0.0;
|
||||
complex<DP> ln_prod2 = 0.0;
|
||||
complex<DP> ln_prod3 = 0.0;
|
||||
complex<DP> ln_prod4 = 0.0;
|
||||
|
||||
for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
ln_prod1 += log(norm(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
if (norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)) > 100.0 * MACHINE_EPS_SQ)
|
||||
ln_prod2 += log(norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
|
||||
|
||||
// Define the F ones earlier...
|
||||
|
||||
for (int j = 0; j < B.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
|
||||
re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
|
||||
im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
|
||||
re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
|
||||
im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
|
||||
re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
|
||||
im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
// for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
// for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
// ln_prod+=log(abs(phi((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a))+eta*0.5)))
|
||||
|
||||
// for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
// for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
// for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
// ln_prod+=-log(abs(phi(-(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a))+eta*0.5)));
|
||||
|
||||
// for (int i = 0; i < B.chain.Nstrings; ++i)
|
||||
// for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
|
||||
// for (int a = 1; a <= B.chain.Str_L[i]; ++a)
|
||||
// for (int j = 0; j < B.chain.Nstrings; ++j)
|
||||
// for (int beta = 0; beta < B.base.Nrap[j]; ++beta)
|
||||
// for (int b = 1; b <= B.chain.Str_L[j]; ++b)
|
||||
// if(i!=j || alpha!=beta ||a!=b)ln_prod3+=-0.5*log(abs(phi((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a))-(B.lambda[j][beta] + 0.5 * II * (B.chain.Str_L[j] + 1.0 - 2.0 * b))-eta)));
|
||||
|
||||
// for (int i = 0; i < A.chain.Nstrings; ++i)
|
||||
// for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
|
||||
// for (int a = 1; a <= A.chain.Str_L[i]; ++a)
|
||||
// for (int j = 0; j < A.chain.Nstrings; ++j)
|
||||
// for (int beta = 0; beta < A.base.Nrap[j]; ++beta)
|
||||
// for (int b = 1; b <= A.chain.Str_L[j]; ++b)
|
||||
// if(abs((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a))-(A.lambda[j][beta] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * b))-eta)!=0 && (i!=j && alpha!=beta && a!=b))
|
||||
// ln_prod3+=-0.5*log(abs((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a))-(A.lambda[j][beta] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * b))-eta));
|
||||
|
||||
|
||||
|
||||
//mu is the ground state!
|
||||
//A -> mu, B -> lam
|
||||
complex<DP> prod=complex<DP>(1.0,0.0);
|
||||
complex<DP> prod2=complex<DP>(1.0,0.0);
|
||||
complex<DP> prod3=complex<DP>(1.0,0.0);
|
||||
for(int l=0; l<sizeA;l++) prod*=phi(mu[l]+eta*0.5);
|
||||
for(int l=0; l<sizeB;l++) prod/=phi(lam[l]+eta*0.5);
|
||||
|
||||
for(int l=0; l<sizeA;l++)
|
||||
for(int m=0; m<sizeA;m++)
|
||||
if(l!=m)prod2*=1.0/sqrt(abs(phi(mu[m]-mu[l]-eta)));
|
||||
for(int l=0; l<sizeB;l++)
|
||||
for(int m=0; m<sizeB;m++)
|
||||
if(abs(lam[m]-lam[l]-eta)!=0 && l!=m)prod3*=1.0/sqrt(abs(phi(lam[m]-lam[l]-eta)));
|
||||
|
||||
result+=2.0*log(abs(prod))-2.0*log(prod3)+2.0*log(prod2) - A.lnnorm - B.lnnorm;// a factor prod3^2 is inserted in the determinant!
|
||||
// cout<<"prod:"<<prod<<endl;
|
||||
SQMat_CX Hm(0.0, A.base.Mdown);
|
||||
//complex<DP> H[sizeA][sizeA];
|
||||
// cout<<"mu[l]:";
|
||||
// for(int l=0; l<sizeA;l++)
|
||||
// cout<<mu[l]<<", ";
|
||||
// cout<<endl;
|
||||
// cout<<"lam[l]:";
|
||||
// for(int l=0; l<sizeB;l++)
|
||||
// cout<<lam[l]<<", ";
|
||||
// cout<<endl;
|
||||
|
||||
int index_a = 0;
|
||||
int index_b = 0;
|
||||
complex<DP> Prod_powerN;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
complex<DP> prodplus= complex<DP>(1.0,0.0);
|
||||
complex<DP> prodminus= complex<DP>(1.0,0.0);
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
|
||||
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
|
||||
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
|
||||
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
|
||||
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] -eta*0.5) /(B.lambda[k][beta] +eta*0.5), complex<DP> (B.chain.Nsites));
|
||||
|
||||
Hm[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
|
||||
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
|
||||
if (b > 1) Hm[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)*exp(ln_Fn_G(A,B,k,beta,b-1))*exp(-real(ln_Fn_F(B, k, beta, b - 1)));//.../ prod_l!=k | phi(lam[l]-lam[k]) |
|
||||
else if (b == 1) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
complex<DP> sum1 = complex<DP>(0.0,0.0);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1] //sum term when i=0
|
||||
- ln_FunctionF[0] - ln_FunctionF[1]);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) //sum term when i=n
|
||||
* exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum)
|
||||
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
|
||||
|
||||
Hm[index_a][index_b] = eta * exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum1 * exp( - real(ln_Fn_F(B, k, beta, b - 1))); //the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements Hm[a][M]
|
||||
|
||||
//Hm[index_a][B.base.Mdown] = one_over_A_lambda_sq_plus_1over2sq;
|
||||
//Hm[index_a][B.base.Mdown] = eta/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) *
|
||||
// (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
|
||||
Hm[index_a][B.base.Mdown] = eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
// cout<<"Hm:";
|
||||
// for(int j=0; j<sizeA;j++){
|
||||
// for(int k=0; k<sizeA;k++) cout<<"Hm["<<j<<"]["<<k<<"]:"<<Hm[j][k]<<", ";
|
||||
// cout<<endl;
|
||||
// }
|
||||
|
||||
complex<DP> F= complex<DP>(0.0,0.0);
|
||||
|
||||
complex<DP> detmatrix;
|
||||
detmatrix=exp(lndet_LU_CX_dstry(Hm));
|
||||
//cout<<"exp(lndet_LU_CX(Hm)):"<<abs(detmatrix)<<endl;
|
||||
// cout<<"exp(i*(A.K-B.K))+1.0):"<<exp(i*(A.K-B.K))+1.0<<"det(matrix):"<<detmatrix<<endl;
|
||||
//F=-(exp(-i*(A.K-B.K))+1.0)*detmatrix;
|
||||
|
||||
//mu is the ground state!
|
||||
//A -> mu, B -> lam
|
||||
SQMat_CX G(0.0, A.base.Mdown);
|
||||
SQMat_CX BbDa(0.0, A.base.Mdown);
|
||||
index_a = 0;
|
||||
|
||||
for (int j = 0; j < A.chain.Nstrings; ++j) {
|
||||
for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
|
||||
for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
|
||||
|
||||
index_b = 0;
|
||||
|
||||
complex<DP> Da;
|
||||
complex<DP> Ca;
|
||||
Da=eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
|
||||
Ca=eta*((mu[index_a]-eta*0.5)+(mu[index_a]+eta*0.5))/pow(((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5)),2.0);
|
||||
|
||||
|
||||
for (int k = 0; k < B.chain.Nstrings; ++k) {
|
||||
for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
|
||||
for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
|
||||
|
||||
/*if (B.chain.Str_L[k] == 1) {
|
||||
|
||||
complex<DP> Bb;
|
||||
Bb=-(phi(lam[index_b]+eta*0.5)+phi(lam[index_b]-eta*0.5));
|
||||
complex<DP> product=complex<DP>(1.0,0.0);
|
||||
for(int o=0; o<sizeB;o++)product*=phi(lam[o]-lam[index_b]+eta);
|
||||
Bb*=product;
|
||||
|
||||
complex<DP> prodplus= complex<DP>(1.0,0.0);
|
||||
complex<DP> prodminus= complex<DP>(1.0,0.0);
|
||||
|
||||
// use simplified code for one-string here: original form of Hm2P matrix
|
||||
prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
|
||||
prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
|
||||
//prodplus*= exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta]);// - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]+eta) / prod_l!=k |phi(lam[l]-lam[k]) |;
|
||||
prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
|
||||
prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
|
||||
// prodminus*= exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta]);// - re_ln_Fn_F_B_0[k][beta]);//Prod phi(mu[l]-lam[k]-eta)/ prod_l!=k | phi(lam[l]-lam[k]) |;
|
||||
|
||||
Prod_powerN = pow((B.lambda[k][beta] - eta*0.5) /(B.lambda[k][beta] + eta*0.5), complex<DP> (B.chain.Nsites));
|
||||
|
||||
G[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
|
||||
BbDa[index_a][index_b]=Bb*Da*exp(- re_ln_Fn_F_B_0[k][beta]);
|
||||
|
||||
} // if (B.chain.Str_L == 1)
|
||||
|
||||
else {
|
||||
*/{
|
||||
|
||||
if (b > 1){
|
||||
G[index_a][index_b] = eta* Fn_K(A, j, alpha, a, B, k, beta, b-1)*exp(ln_Fn_G(A,B,k,beta,b-1))*exp(-real(ln_Fn_F(B, k, beta, b - 1)));//.../ prod_l!=k | phi(lam[l]-lam[k]) |
|
||||
BbDa[index_a][index_b] =0 ;
|
||||
}
|
||||
else if (b == 1) {
|
||||
|
||||
Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
|
||||
|
||||
Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
|
||||
for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
|
||||
|
||||
complex<DP> sum1 = complex<DP>(0.0,0.0);
|
||||
complex<DP> sum2 = complex<DP>(0.0,0.0);
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1]
|
||||
- ln_FunctionF[0] - ln_FunctionF[1]);//sum term when i=0
|
||||
//sum2 doesn't have a i=0 term
|
||||
|
||||
sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
|
||||
* exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
|
||||
- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); //sum term when i=n
|
||||
sum2 += exp(ln_FunctionG[B.chain.Str_L[k]]- ln_FunctionF[B.chain.Str_L[k]] )
|
||||
* (phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * B.chain.Str_L[k]))-eta*0.5)
|
||||
+ phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * B.chain.Str_L[k]))+eta*0.5) ); //sum term when i=n
|
||||
|
||||
for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) {
|
||||
sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
|
||||
exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
|
||||
sum2 += exp(ln_FunctionG[jsum]- ln_FunctionF[jsum] )
|
||||
* (phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * jsum))-eta*0.5)
|
||||
+ phi((B.lambda[k][beta] + 0.5 * II * (B.chain.Str_L[k] + 1.0 - 2.0 * jsum))+eta*0.5) );
|
||||
}
|
||||
|
||||
G[index_a][index_b] = eta * exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum1 * exp( - real(ln_Fn_F(B, k, beta, b - 1))); //the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
|
||||
BbDa[index_a][index_b] = - Da* exp(ln_FunctionF[0]+ ln_FunctionF[1] - ln_FunctionG[1]) * sum2 * exp( - real(ln_Fn_F(B, k, beta, b - 1)));//the absolute value prod_l!=k phi(lam[l]-lam[k]) : real(ln_...)
|
||||
} // else if (b == B.chain.Str_L[k])
|
||||
} // else
|
||||
index_b++;
|
||||
}}} // sums over k, beta, b
|
||||
|
||||
// now define the elements Hm[a][M]
|
||||
|
||||
|
||||
//Hm[index_a][B.base.Mdown] = eta/((A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) * (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
|
||||
G[index_a][B.base.Mdown]=Ca;
|
||||
BbDa[index_a][B.base.Mdown]=0;
|
||||
index_a++;
|
||||
}}} // sums over j, alpha, a
|
||||
|
||||
SQMat_CX matrix(0.0, A.base.Mdown);
|
||||
for(int a=0; a<sizeA;a++)
|
||||
for(int b=0; b<sizeA;b++)
|
||||
matrix[a][b]=G[a][b]+BbDa[a][b];
|
||||
|
||||
// cout<<"matrix:";
|
||||
// for(int j=0; j<sizeA;j++){
|
||||
// for(int k=0; k<sizeA;k++) cout<<"matrix["<<j<<"]["<<k<<"]:"<<matrix[j][k]<<", ";
|
||||
// cout<<endl;
|
||||
// }
|
||||
// cout<<"matrixtest:";
|
||||
// for(int j=0; j<sizeA;j++){
|
||||
// for(int k=0; k<sizeA;k++) cout<<"matrixtest["<<j<<"]["<<k<<"]:"<<matrixtest[j][k]<<", ";
|
||||
// cout<<endl;
|
||||
// }
|
||||
|
||||
// cout<<"BbDa[a][b]:";
|
||||
// for(int j=0; j<sizeA;j++){
|
||||
// for(int k=0; k<sizeA;k++) cout<<"BbDa["<<j<<"]["<<k<<"]:"<<BbDa[j][k]<<", ";
|
||||
// cout<<endl;
|
||||
// }
|
||||
// cout<<"Bn[b]*Da[a]:";
|
||||
// for(int j=0; j<sizeA;j++){
|
||||
// for(int k=0; k<sizeA;k++) cout<<"test["<<j<<"]["<<k<<"]:"<<Bn[k]*Da[j]<<", ";
|
||||
// cout<<endl;
|
||||
// }
|
||||
|
||||
// cout<<"prod:"<<prod<<endl;
|
||||
// cout<<"(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G))):"<<(exp(lndet_LU_CX(matrix))-exp(lndet_LU_CX(G)))<<endl;
|
||||
// cout<<"(exp(lndet_LU_CX_dstry(matrix)):"<<(exp(lndet_LU_CX(matrix)))<<endl;
|
||||
|
||||
//cout<<" an(n):"<<an(n)<<" det(matrix):"<<det(matrix)<< " det(Gn):"<<det(Gn)<<" an(n)*(det(matrix)-det(Gn)):"<<an(n)*(det(matrix)-det(Gn))<<endl;
|
||||
complex<DP> sum=prod*(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G)));
|
||||
//sum=conj(prod)*(exp(lndet_LU_CX_dstry(matrix))-exp(lndet_LU_CX_dstry(G)));
|
||||
|
||||
//cout<<"an(n):"<< an(n)<< "det(matrix):"<<det(matrix)<<" det(Gn):"<<det(Gn)<<endl;
|
||||
|
||||
//sum_nm_test=(0.5*(lam[0]-lam[1])*(eta*eta+4.0*lam[0]*lam[1]))/pow((lam[0]-eta/2.0)*(lam[0]+eta/2.0)*(lam[1]-eta/2.0)*(lam[1]+eta/2.0),2.0)*(0.5*(mu[0]-mu[1])*(eta*eta+4.0*mu[0]*mu[1]))/pow((mu[0]-eta/2.0)*(mu[0]+eta/2.0)*(mu[1]-eta/2.0)*(mu[1]+eta/2.0),2.0);
|
||||
//sum_nm_test=(0.5*(lam[0]-lam[1])*(eta*eta+4.0*lam[0]*lam[1]))*(0.5*(mu[0]-mu[1])*(eta*eta+4.0*mu[0]*mu[1]))/pow((mu[0]-eta/2.0)*(mu[0]+eta/2.0)*(mu[1]-eta/2.0)*(mu[1]+eta/2.0),2.0);
|
||||
//cout<<"F1:"<<F<<endl;
|
||||
// F+=4.0*pow(prod,2)*exp(i*(qlam+qmu))*sum_n;
|
||||
|
||||
// F+=+2.0*exp(i*(A.K-B.K))*sum;
|
||||
|
||||
complex<DP> F2=exp(eta*(B.K-A.K))*(-2.0*sum);
|
||||
complex<DP> F3=(exp(eta*(B.K-A.K)))*(detmatrix);
|
||||
F=detmatrix;
|
||||
// cout<<"F1:"<<F*sqrt(exp(result))<<" F2:"<<F2*sqrt(exp(result))<<" F3:"<<F3*sqrt(exp(result))<<endl;
|
||||
// cout<<"abs(F1)^2:"<<abs(F*F*(exp(result)))<<" abs(F2)^2:"<<abs(F2*F2*(exp(result)))<<" abs(F3)^2:"<<abs(F3*F3*(exp(result)))<<endl;
|
||||
// cout<<"arg(F1):"<<-i*log(F*sqrt(exp(result))/abs(F*sqrt(exp(result))))/M_PI<<" arg(F2):"<<-i*log(F2*sqrt(exp(result))/abs(F2*sqrt(exp(result))))/M_PI<<" arg(F3):"<<-i*log(F3*sqrt(exp(result))/abs(F3*sqrt(exp(result))))/M_PI<<endl;
|
||||
// cout<<"F:"<<(F)<<endl;
|
||||
// cout<<"Smff:"<<exp(result)*4.0*abs(detmatrix*detmatrix)<<endl;
|
||||
F+=exp(i*(A.K-B.K))*(2.0*sum*(-1.0)+detmatrix);
|
||||
|
||||
|
||||
// cout<<"sum:"<<sum<<endl;
|
||||
// cout<<"exp(result):"<<exp(result)<<endl;
|
||||
|
||||
//TEST!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
result+=2.0*log(abs(F));
|
||||
result-=log(A.chain.Nsites-A.base.Mdown*2+2.0);
|
||||
//result*=pow(abs((exp(i*(A.K-B.K))+1.0)*detmatrix),2);//*(exp(i*(A.K-B.K))+1.0)
|
||||
//result*=pow(abs(2.0*exp(i*(A.K-B.K))*sum),2);
|
||||
//result/=(B.chain.Nsites)*1/16.0;
|
||||
//cout<<"TEST::::::::::::::::::::::"<<"A.Check_Admissibility('a'):"<<A.Check_Admissibility('a')<<endl;
|
||||
//cout<<"mu:"<<mu<<" lam:"<<lam<<endl;
|
||||
// cout<<"an(n):"<<an<<endl;
|
||||
// cout<<"prod^2:"<<pow(abs(prod),2)<<endl;
|
||||
// cout<<"prod3:"<<prod3<<endl;
|
||||
// cout<<"prod2:"<<prod2<<endl;
|
||||
|
||||
|
||||
// cout<<"normlam"<<"normmu:"<<(exp(A.lnnorm))<<":"<<(exp(B.lnnorm))<<endl;
|
||||
// cout<<"abs(prod*prod*prod2*sum_n):"<<abs(prod*prod*prod2*sum_n)<<endl;
|
||||
|
||||
|
||||
//cout<<"computation time for Szm:"<<clock()-start_time_local<<endl;
|
||||
complex<DP> ln_ME_sq = result;
|
||||
|
||||
// if (real(ln_ME_sq) > 10.0) ln_ME_sq = complex<DP> (-300.0); // fix for artificial divergences
|
||||
|
||||
delete[] mu;
|
||||
delete[] lam;
|
||||
|
||||
|
||||
//return(ln_ME_sq);
|
||||
return(0.5 * ln_ME_sq); // Return ME, not MEsq
|
||||
|
||||
}
|
||||
|
||||
} // namespace JSC
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue