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

Este commit está contenido en:
J.-S. Caux 2018-02-09 17:34:05 +01:00
padre 61084ef3b3
commit 103cbe84d6
Se han modificado 172 ficheros con 46745 adiciones y 0 borrados

9
.gitignore vendido Archivo normal
Ver fichero

@ -0,0 +1,9 @@
.DS_Store
*~
*tar.gz
bin/*
lib/*
obj/*

492
Makefile Archivo normal
Ver fichero

@ -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
Ver fichero

@ -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.

122
include/JSC.h Archivo normal
Ver fichero

@ -0,0 +1,122 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC.h
Purpose: Core header file, includes all descendents.
***********************************************************/
#ifndef _JSC_H_
#define _JSC_H_
// This core header file includes all the others
const char JSC_VERSION[20] = "ABACUS++G_8";
// Standard includes
#include <cmath>
#include <complex> // for complex number algebra
#include <string>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib> // for exit(), ...
#include <ctime> // for clock(), ...
#include <limits> // for numeric limits
#include <climits> // for numeric limits
// For file sizes, etc
#include "sys/types.h"
#include "sys/stat.h"
#include "unistd.h"
// Signal handling
#include <stdio.h> /* standard I/O functions */
#include <unistd.h> /* standard unix functions, like getpid() */
#include <sys/types.h> /* various type definitions, like pid_t */
#include <signal.h> /* signal name macros, and the signal() prototype */
// My own math functions and shortcuts
#include "JSC_util.h"
// Vectors and matrices
#include "JSC_Vect.h" // My vector class definitions
#include "JSC_Matrix.h" // My matrix class definitions
// Choose_Table
#include "JSC_Combi.h"
// Fitting, interpolating
#include "JSC_Fitting.h"
// Young tableaux
#include "JSC_Young.h"
// Integration
#include "JSC_Integ.h"
// Special functions:
#include "JSC_Spec_Fns.h"
//*** Integrable models:
// Heisenberg spin-1/2 antiferromagnet
#include "JSC_Heis.h"
// Lieb-Liniger
#include "JSC_LiebLin.h"
// One-d spinless fermions:
#include "JSC_ODSLF.h"
// General:
//#include "JSC_Bethe.h"
// Thermodynamic Bethe Ansatz utilities
#include "JSC_TBA.h"
// State ensembles
#include "JSC_State_Ensemble.h"
// XXX in zero field: Uq(sl(2)) stuff
#include "JSC_XXX_h0.h"
// XXZ in zero field: quantum groups
#include "JSC_XXZ_h0.h"
// Two-component Bose gas
//#include "2CBG.h"
// Richardson
//#include "Richardson.h"
// *** Correlation functions:
// New scanning protocols for ABACUS++
#include "JSC_Scan.h"
// Functions for everybody
//#include "JSC_fns.h" // KEEP THIS INCLUDE LAST, SINCE IT USES PREVIOUS DECLARATIONS
// Numerical RG:
#include "JSC_NRG.h"
// OpenMP
#include <omp.h>
// Typedefs:
typedef double DP;
#endif // _JSC_H_

109
include/JSC_Bethe.h Archivo normal
Ver fichero

@ -0,0 +1,109 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_Bethe.h
Purpose: Declares Bethe state-related classes and functions.
***********************************************************/
#ifndef _BETHE_
#define _BETHE_
#include "JSC.h"
namespace JSC {
/*
class Model {
protected:
string Name; // LiebLin, XXZ, XXX, XXZ_gpd
int Nsites; //
int L;
DP interaction;
public:
Model (string Name_ref,
};
*/
class Base {
public:
int charge; // charge of the base: number of particles (LiebLin gas), number of down spins (Heis), ...
Vect<int> Nrap; // Nrap[i] contains the number of rapidities of type i, i = 0, ..., Nstrings - 1.
int Nraptot; // total number of strings in this state
Vect<DP> Ix2_infty; // Ix2_infty[i] contains the max of BAE function for the (half-)integer I[i], i = 0, Nstrings - 1.
Vect<int> Ix2_min;
Vect<int> Ix2_max; // Ix2_max[i] contains the integer part of 2*I_infty, with correct parity for base.
string baselabel;
public:
Base ();
Base (const Base& RefBase); // copy constructor
public: // LiebLin constructors
Base (int N); // Constructor for repulsive LiebLin gas case: one type of particle
public: // HEIS constructors
//Base (const Heis_Chain& RefChain, int M); // constructs configuration with all Mdown in one-string of +1 parity // DEPRECATED
Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities); // sets to Nrapidities vector, and checks consistency
Base (const Heis_Chain& RefChain, string baselabel_ref);
public: // operators
Base& operator= (const Base& RefBase);
bool operator== (const Base& RefBase);
bool operator!= (const Base& RefBase);
public: // member functions
void Compute_Ix2_limits(const Heis_Chain& RefChain); // computes the Ix2_infty and Ix2_max
};
//****************************************************************************
// Class Bethe_State is a wrapper class for all types of eigenstates
class Bethe_State {
public: // configuration
Base base;
Vect<Vect<int> > Ix2;
Vect<Vect<DP> > lambda;
public: // properties
DP E;
int iK;
DP K;
DP lnnorm;
public: // identification
string label; // this is the relative label by default
Vect<Vect<int> > OriginIx2; // to define the relative label
public: // convergence
DP diffsq;
int conv;
int iter;
int iter_Newton;
//public: // for descendents, etc
public: // constructors
Bethe_State();
Bethe_State (const Bethe_State& RefState); // copy constructor
Bethe_State (const Bethe_State& OriginState, string label_ref);
LiebLin_Bethe_State& operator= (const LiebLin_Bethe_State& RefState);
} // namespace JSC
#endif

51
include/JSC_Combi.h Archivo normal
Ver fichero

@ -0,0 +1,51 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS++ library.
Copyright (c) 2006-9.
-----------------------------------------------------------
File: JSC_Combi.h
Purpose: Declares combinatorics-related classes and functions.
Last modified: 08/10/2009
***********************************************************/
#ifndef _COMBI_
#define _COMBI_
#include "JSC.h"
namespace JSC {
//***********************************************************************
class Choose_Table {
private:
int Npower;
int Npowerp1;
int dim;
unsigned long long int* table;
void Fill_table ();
public:
Choose_Table ();
Choose_Table (int Npower_ref);
Choose_Table (const Choose_Table& Ref_Choose_Table); // constructs a new object from an existing one
int power(); // returns Npower
unsigned long long int choose (int N, int M);
~Choose_Table ();
};
std::ostream& operator<< (std::ostream& s, Choose_Table& Ref_table);
} // namespace JSC
#endif

37
include/JSC_Fitting.h Archivo normal
Ver fichero

@ -0,0 +1,37 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC.h
Purpose: Core header file, includes all descendents.
***********************************************************/
#ifndef _FITTING_
#define _FITTING_
namespace JSC {
// Functions in src/FITTING directory
void covsrt (SQMat_DP& covar, Vect<bool>& ia, const int mfit);
void lin_reg (Vect_DP x, Vect_DP y, Vect_DP sigma, DP& a, DP& b, DP& chisq);
void lin_reg (Vect_DP x, Vect_DP y, DP& a, DP& b, DP& chisq);
void mrqmin (Vect_DP& x, Vect_DP& y, Vect_DP& sig, Vect_DP& a,
Vect<bool>& ia, SQMat_DP& covar, SQMat_DP& alpha, DP& chisq,
void funcs(const DP, Vect_DP&, DP&, Vect_DP&), DP& alambda);
void mrqcof (Vect_DP& x, Vect_DP& y, Vect_DP& sig, Vect_DP& a,
Vect<bool>& ia, SQMat_DP& alpha, Vect_DP& beta, DP& chisq,
void funcs (const DP, Vect_DP&, DP&, Vect_DP&));
// For interpolating:
void polint(Vect_DP& xa, Vect_DP& ya, const DP x, DP& y, DP& dy);
void polint(Vect_CX& xa, Vect_CX& ya, const complex<DP> x, complex<DP>& y, complex<DP>& dy);
} // namespace JSC
#endif

777
include/JSC_Heis.h Archivo normal
Ver fichero

@ -0,0 +1,777 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS++ library.
Copyright (c)
-----------------------------------------------------------
File: Heis.h
Purpose: Declares Heisenberg chain classes and functions.
***********************************************************/
#ifndef _HEIS_
#define _HEIS_
#include "JSC.h"
namespace JSC {
// First, some global constants...
const long long int ID_UPPER_LIMIT = 10000000LL; // max size of vectors we can define without seg fault
const int INTERVALS_SIZE = 100000; // size of Scan_Intervals arrays
const int NBASESMAX = 1000; // max number of bases kept
const DP ITER_REQ_PREC = 100.0 * MACHINE_EPS_SQ;
//const DP ITER_REQ_PREC = MACHINE_EPS_SQ;
// Cutoffs on particle numbers
//const int NPARTICLES_MAX = 24;
//const int NHOLES_MAX = NPARTICLES_MAX/2;
//const int MAX_RAPS_ABOVE_ZERO = 10; // max nr of rapidities above lowest type
//const int NPARTICLES_MAX = 2;
//const int NHOLES_MAX = 1;
//const int MAX_TYPES_IN_BASE = 4; // maximal number of particle types we allow in bases
const int MAXSTRINGS = 20; // maximal number of particle types we allow in bases
//const int MAXSTRINGS = 2; // maximal number of particle types we allow in bases
//const DP HEIS_deltaprec = 1.0e-6;//1.0e-4; // maximal string deviation allowed // DEPRECATED in ++T_9
const int NEXC_MAX_HEIS = 16; // maximal number of excitations (string binding/unbinding, particle-hole) considered
//***********************************************************************
class Heis_Chain {
public:
DP J;
DP Delta;
DP anis; // acos(Delta) if Delta < 1.0, 0 if Delta == 1.0, acosh(Delta) if Delta > 1.0
DP hz;
int Nsites;
int Nstrings; // how many possible strings. The following two arrays have Nstrings nonzero elements.
int* Str_L; // vector (length M) containing the allowed string lengths. Elements that are 0 have no meaning.
int* par; // vector (length M) containing the parities of the strings. Elements that are 0 have no meaning.
// Parities are all +1 except for gapless XXZ subcases
DP* si_n_anis_over_2; // for optimization: sin for XXZ, sinh for XXZ_gpd
DP* co_n_anis_over_2; // for optimization
DP* ta_n_anis_over_2; // for optimization
DP prec; // precision required for computations, always put to ITER_REQ_PREC
public:
Heis_Chain ();
Heis_Chain (DP JJ, DP DD, DP hh, int NN); // contructor: simply initializes
Heis_Chain (const Heis_Chain& RefChain); // copy constructor;
Heis_Chain& operator= (const Heis_Chain& RefChain);
bool operator== (const Heis_Chain& RefChain);
bool operator!= (const Heis_Chain& RefChain);
~Heis_Chain(); // destructor
public:
//void Scan_for_Possible_Bases (int Mdown, Vect<long long int>& possible_base_id, int& nfound, int nexc_max_used,
// int base_level_to_scan, Vect<int>& Nrapidities);
//Vect<long long int> Possible_Bases (int Mdown); // returns a vector of possible bases
/* Deactivated in ++G_8
void Scan_for_Possible_Bases (int Mdown, Vect<string>& possible_base_label, int& nfound, int nexc_max_used,
int base_level_to_scan, Vect<int>& Nrapidities);
Vect<string> Possible_Bases (int Mdown); // returns a vector of possible bases
*/
};
//****************************************************************************
// Objects in class Heis_Base are a checked vector containing the number of rapidities of allowable types for a given state
class Heis_Base {
public:
int Mdown; // total number of down spins
Vect<int> Nrap; // Nrap[i] contains the number of rapidities of type i, i = 0, Nstrings - 1.
int Nraptot; // total number of strings in this state
Vect<DP> Ix2_infty; // Ix2_infty[i] contains the max of BAE function for the (half-)integer I[i], i = 0, Nstrings - 1.
Vect<int> Ix2_min;
Vect<int> Ix2_max; // Ix2_max[i] contains the integer part of 2*I_infty, with correct parity for base.
//long long int id; // identification number
double dimH; // dimension of sub Hilbert space associated to this base; use double to avoid max int problems.
string baselabel; // base label
public:
Heis_Base ();
Heis_Base (const Heis_Base& RefBase); // copy constructor
Heis_Base (const Heis_Chain& RefChain, int M); // constructs configuration with all Mdown in one-string of +1 parity
Heis_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities); // sets to Nrapidities vector, and checks consistency
//Heis_Base (const Heis_Chain& RefChain, long long int id_ref);
Heis_Base (const Heis_Chain& RefChain, string baselabel_ref);
inline int& operator[] (const int i);
inline const int& operator[] (const int i) const;
Heis_Base& operator= (const Heis_Base& RefBase);
bool operator== (const Heis_Base& RefBase);
bool operator!= (const Heis_Base& RefBase);
void Compute_Ix2_limits(const Heis_Chain& RefChain); // computes the Ix2_infty and Ix2_max
//void Scan_for_Possible_Types (Vect<long long int>& possible_type_id, int& nfound, int base_level, Vect<int>& Nexcitations);
//Vect<long long int> Possible_Types (); // returns a vector of possible types
};
inline int& Heis_Base::operator[] (const int i)
{
return Nrap[i];
}
inline const int& Heis_Base::operator[] (const int i) const
{
return Nrap[i];
}
//****************************************************************************
/*
// Objects in class Ix2_Config carry all the I's of a given state
class Ix2_Config {
//private:
public:
int Nstrings;
Vect<int> Nrap;
int Nraptot;
//int** Ix2;
Vect<Vect<int> > Ix2;
public:
Ix2_Config ();
Ix2_Config (const Heis_Chain& RefChain, int M); // constructor, puts I's to ground state
Ix2_Config (const Heis_Chain& RefChain, const Heis_Base& base); // constructor, putting I's to lowest-energy config
// consistent with Heis_Base configuration for chain RefChain
Ix2_Config& operator= (const Ix2_Config& RefConfig);
//inline int* operator[] (const int i);
inline Vect<int> operator[] (const int i);
//inline const int* operator[] (const int i) const;
inline const Vect<int> operator[] (const int i) const;
//~Ix2_Config(); // not needed, inherited from Vect
string Return_Label (const Ix2_Config& OriginIx2);
};
//inline int* Ix2_Config::operator[] (const int i)
inline Vect<int> Ix2_Config::operator[] (const int i)
{
return Ix2[i];
}
//inline const int* Ix2_Config::operator[] (const int i) const
inline const Vect<int> Ix2_Config::operator[] (const int i) const
{
return Ix2[i];
}
std::ostream& operator<< (std::ostream& s, const Ix2_Config& RefConfig);
*/
//****************************************************************************
// Objects in class Lambda carry all rapidities of a state
class Lambda {
private:
int Nstrings;
Vect<int> Nrap;
int Nraptot;
DP** lambda;
//Vect<Vect<DP> > lambda;
public:
Lambda ();
Lambda (const Heis_Chain& RefChain, int M); // constructor, puts all lambda's to zero
Lambda (const Heis_Chain& RefChain, const Heis_Base& base); // constructor, putting I's to lowest-energy config
// consistent with Heis_Base configuration for chain RefChain
Lambda& operator= (const Lambda& RefConfig);
inline DP* operator[] (const int i);
//inline Vect<DP> operator[] (const int i);
inline const DP* operator[] (const int i) const;
//inline const Vect<DP> operator[] (const int i) const;
~Lambda();
};
inline DP* Lambda::operator[] (const int i)
//inline Vect<DP> Lambda::operator[] (const int i)
{
return lambda[i];
}
inline const DP* Lambda::operator[] (const int i) const
//inline const Vect<DP> Lambda::operator[] (const int i) const
{
return lambda[i];
}
//****************************************************************************
// Objects in class Ix2_Offsets carry Young tableau representations of the Ix2 configurations
/*
class Ix2_Offsets {
public:
Heis_Base base;
Vect<Young_Tableau> Tableau; // vector of pointers to tableaux at each level
long long int type_id;
long long int id; // id number of offset
long long int maxid; // max id number allowable
public:
Ix2_Offsets ();
Ix2_Offsets (const Ix2_Offsets& RefOffset); // copy constructor
Ix2_Offsets (const Heis_Base& RefBase, long long int req_type_id);
Ix2_Offsets (const Heis_Base& RefBase, Vect<int> nparticles); // sets all tableaux to empty ones, with nparticles[] at each level
Ix2_Offsets& operator= (const Ix2_Offsets& RefOffset);
bool operator<= (const Ix2_Offsets& RefOffsets);
bool operator>= (const Ix2_Offsets& RefOffsets);
public:
void Set_to_id (long long int idnr);
void Compute_id ();
void Compute_type_id ();
public:
bool Add_Boxes_From_Lowest (int Nboxes, bool odd_sectors); // adds Nboxes in minimal energy config, all boxes in either even or odd sectors
};
inline long long int Ix2_Offsets_type_id (Vect<int>& nparticles)
{
long long int type_id_here = 0ULL;
for (int i = 0; i < nparticles.size(); ++i)
type_id_here += nparticles[i] * pow_ulli(10ULL, i);
return(type_id_here);
}
long long int Find_idmin (Ix2_Offsets& scan_offsets, int particle_type, int tableau_level, int Row_L_min);
long long int Find_idmax (Ix2_Offsets& scan_offsets, int particle_type, int tableau_level);
*/
//****************************************************************************
// Objects in class Ix2_Offsets_List carry a vector of used Ix2_Offsets
/*
class Ix2_Offsets_List {
public:
int ndef;
Vect<Ix2_Offsets> Offsets;
public:
Ix2_Offsets_List ();
Ix2_Offsets& Return_Offsets (Heis_Base& RefBase, Vect<int> nparticles); // returns the Ix2_Offsets corresponding to nparticles[]/base
Ix2_Offsets& Return_Offsets (Heis_Base& RefBase, long long int req_type_id);
};
*/
//****************************************************************************
// Objects in class Heis_Bethe_State carry all information about an eigenstate
// Derived classes include XXZ_Bethe_State, XXX_Bethe_State, XXZ_gpd_Bethe_State
// These contain subclass-specific functions and data.
class Heis_Bethe_State {
public:
Heis_Chain chain;
Heis_Base base;
//Ix2_Offsets offsets;
//Ix2_Config Ix2;
Vect<Vect<int> > Ix2;
Lambda lambda;
Lambda deviation; // string deviations
Lambda BE; // Bethe equation for relevant rapidity, in the form BE = theta - (1/N)\sum ... - \pi I/N = 0
DP diffsq; // sum of squares of rapidity differences in last iteration
int conv; // convergence status
DP dev; // sum of absolute values of string deviations
int iter; // number of iterations necessary for convergence
int iter_Newton; // number of iterations necessary for convergence (Newton method)
DP E; // total energy
int iK; // K = 2.0*PI * iK/Nsites
DP K; // total momentum
DP lnnorm; // ln of norm of reduced Gaudin matrix
//long long int base_id;
//long long int type_id;
//long long int id;
//long long int maxid;
//int nparticles;
string label;
public:
Heis_Bethe_State ();
Heis_Bethe_State (const Heis_Bethe_State& RefState); // copy constructor
//Heis_Bethe_State (const Heis_Bethe_State& RefState, long long int type_id_ref); // new state with requested type_id
Heis_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
Heis_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base); // constructor to lowest-energy config with base
//Heis_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref);
virtual ~Heis_Bethe_State () {};
public:
int Charge () { return(base.Mdown); };
//void Set_Ix2_Offsets (const Ix2_Offsets& RefOffset); // sets the Ix2 to given offsets
//void Set_to_id (long long int id_ref);
//void Set_to_id (long long int id_ref, Heis_Bethe_State& RefState);
//int Nparticles (); // counts the number of particles in state once Ix2 offsets set (so type_id is correctly set)
//void Set_to_Label (string label_ref, const Ix2_Config& OriginIx2);
void Set_to_Label (string label_ref, const Vect<Vect<int> >& OriginIx2);
void Set_Label_from_Ix2 (const Vect<Vect<int> >& OriginIx2);
bool Check_Symmetry (); // checks whether the I's are symmetrically distributed
void Compute_diffsq (); // \sum BE[j][alpha]^2
void Find_Rapidities (bool reset_rapidities); // Finds the rapidities
void Find_Rapidities_Twisted (bool reset_rapidities, DP twist); // Finds the rapidities with twist added to RHS of logBE
//void BAE_smackdown (DP max_allowed);
//void Solve_BAE_smackdown (DP max_allowed, int maxruns);
void Solve_BAE_bisect (int j, int alpha, DP req_prec, int itermax);
void Iterate_BAE (DP iter_factor); // Finds new set of lambda[j][alpha] from previous one by simple iteration
void Solve_BAE_straight_iter (DP straight_prec, int max_iter_interp, DP iter_factor);
void Solve_BAE_extrap (DP extrap_prec, int max_iter_extrap, DP iter_factor);
void Iterate_BAE_Newton (); // Finds new set of lambda[j][alpha] from previous one by a Newton step
void Solve_BAE_Newton (DP Newton_prec, int max_iter_Newton);
void Solve_BAE_with_silk_gloves (DP silk_prec, int max_iter_silk, DP iter_factor);
void Compute_lnnorm ();
void Compute_Momentum ();
void Compute_All (bool reset_rapidities); // solves BAE, computes E, K and lnnorm
inline bool Set_to_Inner_Skeleton (int iKneeded, const Vect<Vect<int> >& OriginStateIx2)
{
Ix2[0][0] = Ix2[0][1] - 2;
Ix2[0][base.Nrap[0] - 1] = Ix2[0][base.Nrap[0] - 2] + 2;
(*this).Compute_Momentum();
if (base.Nrap[0] == 0) return(false);
if (iKneeded >= iK) Ix2[0][base.Nrap[0]-1] += 2*(iKneeded - iK);
else Ix2[0][0] += 2*(iKneeded - iK);
if (Ix2[0][0] < base.Ix2_min[0] || Ix2[0][base.Nrap[0]-1] > base.Ix2_max[0]) return(false);
(*this).Set_Label_from_Ix2 (OriginStateIx2);
return(true);
}
void Set_to_Outer_Skeleton (const Vect<Vect<int> >& OriginStateIx2) {
Ix2[0][0] = base.Ix2_min[0] - 4;
Ix2[0][base.Nrap[0]-1] = base.Ix2_max[0] + 4;
(*this).Set_Label_from_Ix2 (OriginStateIx2);
};
void Set_to_Closest_Matching_Ix2_fixed_Base (const Heis_Bethe_State& StateToMatch); // defined in Heis.cc
// Virtual functions, all defined in the derived classes
public:
virtual void Set_Free_lambdas() { JSCerror("Heis_Bethe_State::..."); } // sets the rapidities to solutions of BAEs without scattering terms
virtual bool Check_Admissibility(char option) { JSCerror("Heis_Bethe_State::..."); return(false); }
// verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
virtual void Compute_BE (int j, int alpha) { JSCerror("Heis_Bethe_State::..."); }
virtual void Compute_BE () { JSCerror("Heis_Bethe_State::..."); }
virtual DP Iterate_BAE(int i, int alpha) { JSCerror("Heis_Bethe_State::..."); return(0.0);}
virtual bool Check_Rapidities() { JSCerror("Heis_Bethe_State::..."); return(false); }
virtual DP String_delta () { JSCerror("Heis_Bethe_State::..."); return(0.0); }
virtual void Compute_Energy () { JSCerror("Heis_Bethe_State::..."); }
virtual void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red) { JSCerror("Heis_Bethe_State::..."); }
};
inline bool Is_Inner_Skeleton (Heis_Bethe_State& State) {
return (State.base.Nrap[0] >= 2 && (State.Ix2[0][0] == State.Ix2[0][1] - 2 || State.Ix2[0][State.base.Nrap[0]-1] == State.Ix2[0][State.base.Nrap[0]-2] + 2));
};
inline bool Is_Outer_Skeleton (Heis_Bethe_State& State) {
return (State.Ix2[0][0] == State.base.Ix2_min[0] - 4 && State.Ix2[0][State.base.Nrap[0]-1] == State.base.Ix2_max[0] + 4);
};
inline bool Force_Descent (char whichDSF, Heis_Bethe_State& ScanState, Heis_Bethe_State& RefState, int desc_type_required, int iKmod, DP Chem_Pot)
{
bool force_descent = false;
// Force descent if energy of ScanState is lower than that of RefState
//if (ScanState.E - RefState.E - (ScanState.base.Mdown - RefState.base.Mdown) < 0.0) return(true);
/*
// We force descent if
// 1) - there exists a higher string whose quantum number is still on 0
// AND - there is at most a single particle-hole in the 0 base level
// AND - either the particle or the hole hasn't yet moved.
if (ScanState.base_id/100000LL > 0) { // there is a higher string
int type0 = ScanState.type_id % 10000;
if (type0 == 0
|| type0 == 101 && ScanState.offsets.Tableau[0].id * ScanState.offsets.Tableau[2].id == 0LL
|| type0 == 110 && ScanState.offsets.Tableau[1].id * ScanState.offsets.Tableau[2].id == 0LL
|| type0 == 1001 && ScanState.offsets.Tableau[0].id * ScanState.offsets.Tableau[3].id == 0LL
|| type0 == 1010 && ScanState.offsets.Tableau[1].id * ScanState.offsets.Tableau[3].id == 0LL) // single p-h pair in base level 0
for (int j = 1; j < ScanState.chain.Nstrings; ++j) {
if (ScanState.base[j] == 1 && ScanState.Ix2[j][0] == 0) {
force_descent = true;
}
}
}
*/
// Force descent if quantum nr distribution is symmetric:
//if (ScanState.Check_Symmetry()) force_descent = true;
//if (desc_type_required > 8 && ScanState.Check_Symmetry()) force_descent = true;
// Force descent for longitudinal if we're at zero or pi momentum:
//ScanState.Compute_Momentum();
//if (whichDSF == 'z' && (ScanState.iK - RefState.iK) % iKmod == 0) force_descent = true;
//if (desc_type_required > 8 && whichDSF == 'z' && (2*(ScanState.iK - RefState.iK) % iKmod == 0)) force_descent = true; // type_req > 8 means that we don't conserve momentum
// Force descent for all DSFs if we're at K = 0 or PI and not conserving momentum upon descent:
if (desc_type_required > 8 && (2*(ScanState.iK - RefState.iK) % iKmod == 0)) force_descent = true; // type_req > 8 means that we don't conserve momentum
//if (force_descent) cout << "Forcing descent on state with label " << ScanState.label << endl;
if (ScanState.chain.Delta > 1.0) {
/*
// Count the nr of holes in one-strings:
int nholes = 0;
for (int i = 0; i < ScanState.base.Nrap[0] - 1; ++i) if (ScanState.Ix2[0][i+1] - ScanState.Ix2[0][i] != 2) nholes++;
if (nholes <= 2) {
if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 2 && ScanState.base.Nrap[1] == 1) force_descent = true;
if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 3 && ScanState.base.Nrap[2] == 1) force_descent = true;
if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 4 && ScanState.base.Nrap[1] == 2) force_descent = true;
}
*/
if (ScanState.label.compare(0, 10, "14x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "14x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "14x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "14x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "14x1y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "14x1y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_0x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_1x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "12x1y2_2x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "13x2y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "30x1y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_0x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_1x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "28x1y2_2x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "29x2y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "46x1y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_0x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_1x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "44x1y2_2x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "45x2y1_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_2x0") == 0) force_descent = true;
//if (ScanState.label.compare(0, 10, "62x1y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
if (ScanState.label.compare(0, 10, "62x1y1_2x1") == 0
&& (desc_type_required == 14 || desc_type_required == 13 || desc_type_required == 11 || desc_type_required == 10)) force_descent = true;
/*
if (ScanState.label.compare(0, 10, "60x1y2_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_0x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_1x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_2x1") == 0 && desc_type_required < 2) force_descent = true;
if (ScanState.label.compare(0, 10, "60x1y2_2x2") == 0 && desc_type_required < 2) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "61x2y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
*/
if (ScanState.label.compare(0, 11, "126x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "126x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "126x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "126x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "126x1y1_2x0") == 0) force_descent = true;
//if (ScanState.label.compare(0, 11, "126x1y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
if (ScanState.label.compare(0, 11, "126x1y1_2x1") == 0
&& (desc_type_required == 14 || desc_type_required == 13 || desc_type_required == 11 || desc_type_required == 10)) force_descent = true;
/*
if (ScanState.label.compare(0, 10, "124x1y2_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_0x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_1x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_2x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "124x1y2_2x2") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 10, "125x2y1_2x1") == 0) force_descent = true;
*/
if (ScanState.label.compare(0, 11, "254x1y1_0x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "254x1y1_0x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "254x1y1_1x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "254x1y1_1x1") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "254x1y1_2x0") == 0) force_descent = true;
if (ScanState.label.compare(0, 11, "254x1y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
// Do not force descent a state with rapidities outside of fundamental interval:
/*
for (int j = 0; j < ScanState.chain.Nstrings; ++j) {
// Logic: allow rapidities -PI/2 <= lambda <= PI/2 (including boundaries)
if (ScanState.base.Nrap[j] > 0 &&
(ScanState.lambda[j][0] < -PI/2 || ScanState.lambda[j][ScanState.base.Nrap[j] - 1] > PI/2))
force_descent = false;
// rapidities should also be ordered as the quantum numbers:
for (int alpha = 1; alpha < ScanState.base.Nrap[j]; ++alpha)
if (ScanState.lambda[j][alpha - 1] >= ScanState.lambda[j][alpha])
force_descent = false;
}
*/
//if (force_descent) cout << "Forcing descent on state with label " << ScanState.label << endl;
} // if Delta > 1
//if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 2 && ScanState.base.Nrap[1] == 1 && ScanState.Ix2[1][0] == 0) force_descent = true;
//if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 3 && ScanState.base.Nrap[2] == 1 && ScanState.Ix2[2][0] == 0) force_descent = true;
//if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 4 && ScanState.base.Nrap[1] == 2 && ScanState.Ix2[1][0] == -1 && ScanState.Ix2[1][1] == 1) force_descent = true;
return(force_descent);
}
std::ostream& operator<< (std::ostream& s, const Heis_Bethe_State& state);
//****************************************************************************
// Objects in class XXZ_Bethe_State carry all extra information pertaining to XXZ gapless
class XXZ_Bethe_State : public Heis_Bethe_State {
public:
Lambda sinhlambda;
Lambda coshlambda;
Lambda tanhlambda;
public:
XXZ_Bethe_State ();
XXZ_Bethe_State (const XXZ_Bethe_State& RefState); // copy constructor
XXZ_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
XXZ_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base); // constructor to lowest-energy config with base
//XXZ_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with bas
public:
XXZ_Bethe_State& operator= (const XXZ_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
void Compute_sinhlambda();
void Compute_coshlambda();
void Compute_tanhlambda();
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
bool Check_Rapidities(); // checks that all rapidities are not nan
DP String_delta ();
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXZ specific functions:
public:
};
XXZ_Bethe_State Add_Particle_at_Center (const XXZ_Bethe_State& RefState);
XXZ_Bethe_State Remove_Particle_at_Center (const XXZ_Bethe_State& RefState);
//****************************************************************************
// Objects in class XXX_Bethe_State carry all extra information pertaining to XXX antiferromagnet
class XXX_Bethe_State : public Heis_Bethe_State {
public:
XXX_Bethe_State ();
XXX_Bethe_State (const XXX_Bethe_State& RefState); // copy constructor
XXX_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
XXX_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base); // constructor to lowest-energy config with base
//XXX_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with base
public:
XXX_Bethe_State& operator= (const XXX_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
bool Check_Rapidities(); // checks that all rapidities are not nan
DP String_delta ();
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXX specific functions
public:
bool Check_Finite_rap ();
};
XXX_Bethe_State Add_Particle_at_Center (const XXX_Bethe_State& RefState);
XXX_Bethe_State Remove_Particle_at_Center (const XXX_Bethe_State& RefState);
//****************************************************************************
// Objects in class XXZ_gpd_Bethe_State carry all extra information pertaining to XXZ gapped antiferromagnets
class XXZ_gpd_Bethe_State : public Heis_Bethe_State {
public:
Lambda sinlambda;
Lambda coslambda;
Lambda tanlambda;
public:
XXZ_gpd_Bethe_State ();
XXZ_gpd_Bethe_State (const XXZ_gpd_Bethe_State& RefState); // copy constructor
XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base); // constructor to lowest-energy config with base
//XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with base
public:
XXZ_gpd_Bethe_State& operator= (const XXZ_gpd_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
void Compute_sinlambda();
void Compute_coslambda();
void Compute_tanlambda();
int Weight(); // weight function for contributions cutoff
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
void Iterate_BAE_Newton();
bool Check_Rapidities(); // checks that all rapidities are not nan and are in interval ]-PI/2, PI/2]
DP String_delta ();
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXZ_gpd specific functions
public:
};
XXZ_gpd_Bethe_State Add_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState);
XXZ_gpd_Bethe_State Remove_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState);
//***********************************************
// Function declarations
// in M_vs_H.cc
DP Ezero (DP Delta, int N, int M);
DP H_vs_M (DP Delta, int N, int M);
DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref);
int M_vs_H (DP Delta, int N, DP HZ);
DP X_avg (char xyorz, DP Delta, int N, int M);
DP Chemical_Potential (const Heis_Bethe_State& RefState);
DP Particle_Hole_Excitation_Cost (char whichDSF, Heis_Bethe_State& AveragingState);
//DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& RefState, DP Chem_Pot, bool fixed_iK, int iKneeded);
DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
void Evaluate_F_Sumrule (string prefix, char whichDSF, const Heis_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
complex<DP> ln_Sz_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B);
complex<DP> ln_Smin_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B);
complex<DP> ln_Sz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
complex<DP> ln_Smin_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
// From Antoine Klauser:
complex<DP> ln_Szz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
complex<DP> ln_Szm_p_Smz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
complex<DP> ln_Smm_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
complex<DP> ln_Sz_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B);
complex<DP> ln_Smin_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B);
// The following functions have become member functions.
//DP String_delta (XXZ_Bethe_State& state);
//DP String_delta (XXX_Bethe_State& state);
//DP String_delta (XXZ_gpd_Bethe_State& state);
//DP Compute_Form_Factor_Entry (char whichDSF, Heis_Bethe_State& LeftState, Heis_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState,
// XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState,
XXZ_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState,
// XXX_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState,
XXX_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState,
// XXZ_gpd_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState,
XXZ_gpd_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
// For geometric quench:
complex<DP> ln_Overlap (XXX_Bethe_State& A, XXX_Bethe_State& B);
void Scan_Heis_Geometric_Quench (DP Delta, int N_1, int M, long long int base_id_1, long long int type_id_1, long long int id_1,
int N_2, int iKmin, int iKmax, int Max_Secs, bool refine);
} // namespace JSC
#endif

32
include/JSC_Infprec.h Archivo normal
Ver fichero

@ -0,0 +1,32 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_Infprec.h
Purpose: Declarations for infinite precision arithmetic classes.
***********************************************************/
#ifndef _JSC_INFPREC_
#define _JSC_INFPREC_
namespace JSC {
class infprec_int {
private:
int nintrep; // number of integers used in representation
int baseint; // fundamental int
Vect<unsigned int> xint; // extra integers
}
} // namespace JSC
#endif

331
include/JSC_Integ.h Archivo normal
Ver fichero

@ -0,0 +1,331 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS++ library.
Copyright (c)
-----------------------------------------------------------
File: JSC_Integ.h
Purpose: Declares combinatorics-related classes and functions.
***********************************************************/
#ifndef _INTEG_
#define _INTEG_
#include "JSC.h"
namespace JSC {
//********************** Class Domain ************************
template<class T>
class Domain {
private:
Vect<T> bdry;
public:
Domain () : bdry(Vect<T>(2))
{
bdry[0] = T(0);
bdry[1] = T(0);
}
public:
Domain (T xmin_ref, T xmax_ref) : bdry(Vect<T>(2))
{
if (xmax_ref < xmin_ref) JSCerror("Use xmax > xmin in Domain.");
bdry[0] = xmin_ref;
bdry[1] = xmax_ref;
}
public:
inline T xmin (int i)
{
if (i > bdry.size()/2) JSCerror("i index too high in Domain::xmin.");
return(bdry[2*i]);
}
public:
inline T xmax (int i)
{
if (i > bdry.size()/2) JSCerror("i index too high in Domain::xmax.");
return(bdry[2*i + 1]);
}
public:
inline int Ndomains ()
{
return(bdry.size()/2);
}
public:
void Include (T xmin_ref, T xmax_ref) {
// Determine the indices of xmin_ref & xmax_ref
int xmin_reg = -1;
int xmax_reg = -1;
for (int i = 0; i < bdry.size(); ++i) {
if ((i+1) % 2 && bdry[i] <= xmin_ref) xmin_reg++;
if (i % 2 && bdry[i] < xmin_ref) xmin_reg++;
if ((i+1) % 2 && bdry[i] <= xmax_ref) xmax_reg++;
if (i % 2 && bdry[i] < xmax_ref) xmax_reg++;
}
//cout << "Include: xmin_reg = " << xmin_reg << "\txmax_reg = " << xmax_reg << endl;
Vect<T> new_bdry(bdry.size() + 2 * ((xmin_reg % 2 && xmax_reg % 2) - (xmax_reg - xmin_reg)/2));
int ishift = 0;
for (int i = 0; i <= xmin_reg; ++i) new_bdry[i] = bdry[i];
if (xmin_reg % 2) {
new_bdry[xmin_reg + 1] = xmin_ref;
ishift++;
if (xmax_reg % 2) {
new_bdry[xmin_reg + 2] = xmax_ref;
ishift++;
}
}
else if ((xmin_reg + 1) % 2 && xmax_reg % 2) {
new_bdry[xmin_reg + 1] = xmax_ref;
ishift++;
}
for (int i = xmin_reg + ishift + 1; i < new_bdry.size(); ++i)
new_bdry[i] = bdry[xmax_reg - xmin_reg - ishift + i];
bdry = new_bdry;
return;
}
public:
void Exclude (T xmin_ref, T xmax_ref) {
// Determine the indices of xmin_ref & xmax_ref
int xmin_reg = -1;
int xmax_reg = -1;
for (int i = 0; i < bdry.size(); ++i) {
if ((i+1) % 2 && bdry[i] <= xmin_ref) xmin_reg++;
if (i % 2 && bdry[i] < xmin_ref) xmin_reg++;
if ((i+1) % 2 && bdry[i] <= xmax_ref) xmax_reg++;
if (i % 2 && bdry[i] < xmax_ref) xmax_reg++;
}
//cout << "Exclude: xmin_reg = " << xmin_reg << "\txmax_reg = " << xmax_reg << endl;
Vect<T> new_bdry(bdry.size() + 2 * (((xmin_reg + 1) % 2 && (xmax_reg + 1) % 2) - (xmax_reg - xmin_reg)/2));
int ishift = 0;
for (int i = 0; i <= xmin_reg; ++i) new_bdry[i] = bdry[i];
if ((xmin_reg + 1) % 2) {
new_bdry[xmin_reg + 1] = xmin_ref;
ishift++;
if ((xmax_reg + 1) % 2) {
new_bdry[xmin_reg + 2] = xmax_ref;
ishift++;
}
}
else if (xmin_reg % 2 && (xmax_reg + 1) % 2) {
new_bdry[xmin_reg + 1] = xmax_ref;
ishift++;
}
for (int i = xmin_reg + ishift + 1; i < new_bdry.size(); ++i)
new_bdry[i] = bdry[xmax_reg - xmin_reg - ishift + i];
bdry = new_bdry;
return;
}
};
template<class T>
std::ostream& operator<< (std::ostream& s, Domain<T> dom)
{
for (int i = 0; i < dom.Ndomains(); ++i) {
if (i > 0) s << endl;
s << dom.xmin(i) << "\t" << dom.xmax(i);
}
return(s);
}
// ********************************* struct I_table ************************
struct I_table {
DP (*function) (DP, DP);
int Nvals;
DP rhomin;
DP rhomax;
DP alpha;
DP logalpha;
DP prec;
//Vect_DP rho_tbl;
//Vect_DP I_tbl;
DP* rho_tbl;
DP* I_tbl;
I_table (DP (*function) (DP, DP), DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec);
DP Return_val (DP req_rho);
void Save ();
bool Load (DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec);
};
// ********************************* struct Integral_table ************************
struct Integral_table {
DP (*function) (DP, DP, int);
int Nvals;
DP rhomin;
DP rhomax;
DP alpha;
DP logalpha;
DP prec;
int maxnrpts;
DP* rho_tbl;
DP* I_tbl;
Integral_table (DP (*function) (DP, DP, int), const char* filenameprefix_ref, DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec, int max_nr_pts);
DP Return_val (DP req_rho);
void Save (const char* filenameprefix);
bool Load (const char* filenameprefix, DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec, int max_nr_pts);
};
// ******************************** Recursive integration functions ******************************
DP Integrate_Riemann (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, int Npts);
DP Integrate_Riemann_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, int Npts);
DP Integrate_rec (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, DP req_prec, int max_rec_level);
DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int max_rec_level);
DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile);
DP Integrate_rec_using_table_and_file (DP (*function) (Vect_DP, I_table, ofstream&), Vect_DP& args, int arg_to_integ, I_table Itable,
DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile);
// ******************************** Recursive version: optimal ******************************
struct data_pt {
DP x;
DP f;
DP dx;
};
struct Integral_result {
DP integ_est;
DP abs_prec;
DP rel_prec;
int n_vals;
};
std::ostream& operator<< (std::ostream& s, const Integral_result& res);
class Integral_data {
private:
data_pt* data;
DP* abs_d2f_dx; // second derivative * dx
DP max_abs_d2f_dx; //
public:
//int n_vals;
Integral_result integ_res;
public:
DP xmin;
DP xmax;
public:
Integral_data (DP (*function_ref) (Vect_DP), Vect_DP& args, int arg_to_integ_ref, DP xmin_ref, DP xmax_ref);
Integral_data (DP (*function_ref) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ_ref, I_table Itable, DP xmin_ref, DP xmax_ref);
Integral_data (DP (*function_ref) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ_ref, Integral_table Itable, DP xmin_ref, DP xmax_ref);
void Save (ofstream& outfile);
void Improve_estimate (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, int Npts_max);
void Improve_estimate (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, int Npts_max);
void Improve_estimate (DP (*function) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ, Integral_table Itable, int Npts_max);
~Integral_data ();
};
Integral_result Integrate_optimal (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, Integral_table Itable), Vect_DP& args, int arg_to_integ,
Integral_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile);
// ******************************** Recursive version: optimal, complex implementation ******************************
// NB: function returns complex values but takes real arguments
struct data_pt_CX {
DP x;
complex<DP> f;
DP dx;
};
struct Integral_result_CX {
complex<DP> integ_est;
DP abs_prec;
DP rel_prec;
int n_vals;
};
class Integral_data_CX {
private:
data_pt_CX* data;
DP* abs_d2f_dx; // second derivative * dx
DP max_abs_d2f_dx; //
public:
//int n_vals;
Integral_result_CX integ_res;
public:
DP xmin;
DP xmax;
public:
Integral_data_CX (complex<DP> (*function_ref) (Vect_DP), Vect_DP& args, int arg_to_integ_ref, DP xmin_ref, DP xmax_ref);
//Integral_data_CX (complex<DP> (*function_ref) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ_ref, I_table Itable, DP xmin_ref, DP xmax_ref);
void Save (ofstream& outfile);
void Improve_estimate (complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, int Npts_max);
//void Improve_estimate (complex<DP> (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, int Npts_max);
~Integral_data_CX ();
};
Integral_result_CX Integrate_optimal (complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax,
DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
//Integral_result_CX Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
// I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
//Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ,
// I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile);
} // namespace JSC
#endif

190
include/JSC_LiebLin.h Archivo normal
Ver fichero

@ -0,0 +1,190 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_LiebLin.h
Purpose: Declares LiebLin gas-related classes and functions.
***********************************************************/
#ifndef _LIEBLIN_
#define _LIEBLIN_
#include "JSC.h"
namespace JSC {
// First, some global constants...
//const DP ITER_REQ_PREC_LIEBLIN = 1.0e+6 * MACHINE_EPS_SQ;
const DP ITER_REQ_PREC_LIEBLIN = 1.0e+4 * MACHINE_EPS_SQ;
const int LIEBLIN_Ix2_MIN = -1000000; // Like a UV cutoff. Assumption: never reached in scanning.
const int LIEBLIN_Ix2_MAX = -LIEBLIN_Ix2_MIN;
//***********************************************************************
//class LiebLin_Bethe_State : public Bethe_State {
class LiebLin_Bethe_State {
public:
DP c_int; // interaction parameter
DP L;
DP cxL;
int N;
string label;
//Vect<int> OriginStateIx2; // quantum numbers of state on which excitations are built; always ordered
Vect<int> Ix2_available; // quantum numbers which are allowable but not occupied
Vect<int> index_first_hole_to_right;
Vect<int> displacement;
Vect<int> Ix2;
Vect<DP> lambdaoc;
//Vect<DP> BE;
Vect<DP> S; // scattering sum
Vect<DP> dSdlambdaoc; // its derivative
DP diffsq;
DP prec;
int conv;
int iter_Newton;
DP E;
int iK;
DP K;
DP lnnorm;
public:
LiebLin_Bethe_State ();
LiebLin_Bethe_State (DP c_int_ref, DP L_ref, int N_ref);
LiebLin_Bethe_State& operator= (const LiebLin_Bethe_State& RefState);
public:
int Charge () { return(N); };
void Set_to_Label (string label_ref, const Vect<int>& OriginStateIx2);
void Set_to_Label (string label_ref); // assumes OriginState == GroundState
void Set_Label_from_Ix2 (const Vect<int>& OriginStateIx2);
void Set_Label_Internals_from_Ix2 (const Vect<int>& OriginStateIx2);
bool Check_Admissibility(char whichDSF); // always returns true
void Find_Rapidities (bool reset_rapidities);
bool Check_Rapidities(); // checks that all rapidities are not nan
DP String_delta(); // trivially returns 0; exists to mirror spin chain function
bool Check_Symmetry (); // checks whether set of quantum numbers obeys { I } = { -I }
void Compute_lnnorm ();
void Compute_All (bool reset_rapidities); // solves BAE, computes E, K and lnnorm
void Set_Free_lambdaocs();
void Iterate_BAE(DP damping);
void Iterate_BAE_S(DP damping);
void Iterate_BAE_Newton(DP damping);
void Compute_Energy ();
void Compute_Momentum ();
DP Kernel (int a, int b);
DP Kernel (DP lambdaoc_ref);
void Build_Reduced_Gaudin_Matrix (SQMat<DP>& Gaudin_Red);
void Build_Reduced_BEC_Quench_Gaudin_Matrix (SQMat<DP>& Gaudin_Red);
void Annihilate_ph_pair (int ipart, int ihole, const Vect<int>& OriginStateIx2);
void Parity_Flip (); // takes all lambdaoc to -lambdaoc
inline bool Set_to_Inner_Skeleton (int iKneeded, const Vect<int>& OriginIx2)
{
if (N < 3) JSCerror("N<3 incompatible with fixed momentum scanning");
Ix2[0] = Ix2[1] - 2;
Ix2[N-1] = Ix2[N-2] + 2;
(*this).Compute_Momentum();
if (iKneeded >= iK) Ix2[N-1] += 2*(iKneeded - iK);
else Ix2[0] += 2*(iKneeded - iK);
if (Ix2[0] < LIEBLIN_Ix2_MIN || Ix2[N-1] > LIEBLIN_Ix2_MAX) return(false);
(*this).Set_Label_from_Ix2 (OriginIx2);
return(true);
}
void Set_to_Outer_Skeleton (const Vect<int>& OriginIx2)
{
Ix2[0] = LIEBLIN_Ix2_MIN + (N % 2) + 1;
Ix2[N-1] = LIEBLIN_Ix2_MAX - (N % 2) - 1;
(*this).Set_Label_from_Ix2 (OriginIx2);
//cout << "Set state to outer skeleton: Ix2 " << (*this).Ix2 << endl;
//cout << "label " << (*this).label << endl;
};
};
inline bool Is_Inner_Skeleton (LiebLin_Bethe_State& State) {
return (State.N >= 2 && (State.Ix2[0] == State.Ix2[1] - 2 || State.Ix2[State.N-1] == State.Ix2[State.N-2] + 2));
};
inline bool Is_Outer_Skeleton (LiebLin_Bethe_State& State) {
return (State.N >= 2 && State.Ix2[0] == LIEBLIN_Ix2_MIN + (State.N % 2) + 1 && State.Ix2[State.N-1] == LIEBLIN_Ix2_MAX - (State.N % 2) - 1);
};
inline bool Is_Outer_Skeleton (const LiebLin_Bethe_State& State) {
return (State.N >= 2 && State.Ix2[0] == LIEBLIN_Ix2_MIN + (State.N % 2) + 1 && State.Ix2[State.N-1] == LIEBLIN_Ix2_MAX - (State.N % 2) - 1);
};
inline bool Force_Descent (char whichDSF, LiebLin_Bethe_State& ScanState, LiebLin_Bethe_State& RefState, int desc_type_required, int iKmod, DP Chem_Pot)
{
bool forcedesc = false;
// Force descent if we're computing density-density, we're at zero momentum and we're descending with momentum preserved:
if (whichDSF == 'd' && ScanState.iK == RefState.iK && desc_type_required > 8) forcedesc = true;
// For BEC to c > 0 quench, g2(x=0): force first step
else if (whichDSF == 'B' && ScanState.label == RefState.label) forcedesc = true;
else if (whichDSF == 'C' && ScanState.label == RefState.label) forcedesc = true;
return(forcedesc);
}
std::ostream& operator<< (std::ostream& s, const LiebLin_Bethe_State& state);
// FUNCTION DECLARATIONS:
DP Chemical_Potential (LiebLin_Bethe_State& RefState);
DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
void Evaluate_F_Sumrule (char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax, const char* RAW_Cstr, const char* FSR_Cstr);
void Evaluate_F_Sumrule (string prefix, char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
void Evaluate_F_Sumrule (char whichDSF, DP c_int, DP L, int N, DP kBT, int nstates_req, DP Chem_Pot, int iKmin, int iKmax, const char* FSR_Cstr);
// in LiebLin_Utils.cc
DP LiebLin_dE0_dc (DP c_int, DP L, int N);
DP LiebLin_vs (DP c_int, DP L, int N);
DP LiebLin_Dressed_Charge_N (DP c_int, DP L, int N);
int Momentum_Right_Excitations (LiebLin_Bethe_State& ScanState);
int Momentum_Left_Excitations (LiebLin_Bethe_State& ScanState);
DP ln_Overlap_with_BEC (LiebLin_Bethe_State& lambda);
DP Particle_Hole_Excitation_Cost (char whichDSF, LiebLin_Bethe_State& AveragingState);
complex<DP> ln_Density_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate);
complex<DP> ln_Psi_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate);
complex<DP> ln_g2_ME (LiebLin_Bethe_State& mu, LiebLin_Bethe_State& lambda);
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState,
// LiebLin_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState,
LiebLin_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
DP LiebLin_Twisted_lnnorm (Vect<complex<DP> >& lambdaoc, double cxL);
complex<DP> LiebLin_Twisted_ln_Overlap (DP expbeta, Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
complex<DP> LiebLin_Twisted_ln_Overlap (complex<DP> expbeta, Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
complex<DP> LiebLin_ln_Overlap (Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
complex<DP> LiebLin_ln_Overlap (Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
// In src/LiebLin_Tgt0.cc:
//DP Entropy_rho (LiebLin_Bethe_State& RefState, int Delta);
//DP Entropy_Fixed_Delta (LiebLin_Bethe_State& RefState, int Delta);
//DP Entropy (LiebLin_Bethe_State& RefState, int Delta);
DP Entropy (LiebLin_Bethe_State& RefState);
//DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, int Delta);
DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT);
//DP Entropy (LiebLin_Bethe_State& RefState, DP epsilon);
//DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, DP epsilon);
//LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, int Delta);
//LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, DP epsilon);
LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT);
LiebLin_Bethe_State Add_Particle_at_Center (const LiebLin_Bethe_State& RefState);
LiebLin_Bethe_State Remove_Particle_at_Center (const LiebLin_Bethe_State& RefState);
DP rho_of_lambdaoc_1 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta);
DP rho_of_lambdaoc_2 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta);
} // namespace JSC
#endif

440
include/JSC_Matrix.h Archivo normal
Ver fichero

@ -0,0 +1,440 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_Matrix.h
Purpose: Declares square matrix class.
***********************************************************/
#ifndef _MATRIX_
#define _MATRIX_
namespace JSC {
// CLASS DEFINITIONS
template <class T>
class SQMat {
private:
int dim;
T** M;
public:
SQMat (int N); // initializes all elements of this n by n matrix to zero
SQMat (const SQMat& rhs); // copy constructor
SQMat (const T& a, int N); // initialize to diagonal matrix with value a (NOT like in NR !!!)
SQMat (const SQMat& a, const SQMat& b); // initialize to tensor product of a and b
SQMat (const SQMat& a, int row_id, int col_id); // init by cutting row row_id and col col_id
void Print ();
SQMat& operator= (const SQMat& rhs); // assignment
SQMat& operator= (const T& a); // assign 1 to diagonal elements (NOT like in NR !!!)
inline T* operator[] (const int i); // subscripting: pointer to row i
inline const T* operator[] (const int i) const;
SQMat& operator+= (const T& a);
SQMat& operator+= (const SQMat& a);
SQMat& operator-= (const T& a);
SQMat& operator-= (const SQMat& a);
SQMat& operator*= (const T& a);
SQMat& operator*= (const SQMat& a);
inline int size() const;
~SQMat();
};
template <class T>
SQMat<T>::SQMat (int N) : dim(N) , M(new T*[N])
{
M[0] = new T[N*N];
for (int i = 1; i < N; i++) M[i] = M[i-1] + N;
}
template <class T>
SQMat<T>::SQMat (const SQMat& rhs) : dim(rhs.dim) , M(new T*[dim])
{
int i,j;
M[0] = new T[dim*dim];
for (i = 1; i < dim; i++) M[i] = M[i-1] + dim;
for (i = 0; i < dim; i++)
for (j = 0; j < dim; j++) M[i][j] = rhs[i][j];
}
template <class T>
SQMat<T>::SQMat (const T& a, int N) : dim(N) , M(new T*[dim])
{
int i, j;
M[0] = new T[dim*dim];
for (i = 1; i < dim; i++) M[i] = M[i-1] + dim;
for (i = 0; i < dim; i++) {
for (j = 0; j < dim; j++) M[i][j] = T(0);
M[i][i] = a;
}
}
template <class T>
SQMat<T>::SQMat (const SQMat& a, const SQMat& b) : dim (a.dim * b.dim) , M(new T*[a.dim * b.dim])
{
M[0] = new T[a.dim * b.dim * a.dim * b.dim];
for (int i = 1; i < a.dim * b.dim; ++i) M[i] = M[i-1] + a.dim * b.dim;
for (int i1 = 0; i1 < a.dim; ++i1) {
for (int i2 = 0; i2 < a.dim; ++i2) {
for (int j1 = 0; j1 < b.dim; ++j1) {
for (int j2 = 0; j2 < b.dim; ++j2) {
M[i1 * (b.dim) + j1][i2 * (b.dim) + j2] = a[i1][i2] * b[j1][j2];
}
}
}
}
}
template <class T>
SQMat<T>::SQMat (const SQMat&a, int row_id, int col_id) : dim (a.dim - 1) , M(new T*[dim])
{
if (dim == 0) {
JSCerror("Error: chopping a row and col from size one matrix.");
exit(1);
}
M[0] = new T[dim * dim];
for (int i = 1; i < dim; ++i) M[i] = M[i-1] + dim;
for (int i = 0; i < row_id; ++i)
for (int j = 0; j < col_id; ++j) M[i][j] = a[i][j];
for (int i = row_id; i < dim; ++i)
for (int j = 0; j < col_id; ++j) M[i][j] = a[i+1][j];
for (int i = 0; i < row_id; ++i)
for (int j = col_id; j < dim; ++j) M[i][j] = a[i][j+1];
for (int i = row_id; i < dim; ++i)
for (int j = col_id; j < dim; ++j) M[i][j] = a[i+1][j+1];
}
// operators
template <class T>
void SQMat<T>::Print ()
{
cout << endl;
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j) cout << M[i][j] << " ";
cout << endl;
}
cout << endl;
}
template <class T>
SQMat<T>& SQMat<T>::operator= (const SQMat<T>& rhs)
{
if (this != &rhs) {
if (dim != rhs.dim) {
JSCerror("Assignment between matrices of different dimensions. Bailing out.");
exit(1);
}
for (int i = 0; i < dim; ++i)
for (int j = 0; j < dim; ++j) M[i][j] = rhs[i][j];
}
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator= (const T& a)
{
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j)
M[i][j] = T(0);
M[i][i] = a;
}
return *this;
}
template <class T>
inline T* SQMat<T>::operator[] (const int i)
{
return M[i];
}
template <class T>
inline const T* SQMat<T>::operator[] (const int i) const
{
return M[i];
}
template <class T>
SQMat<T>& SQMat<T>::operator+= (const T& a)
{
for (int i = 0; i < dim; ++i) M[i][i] += a;
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator+= (const SQMat<T>& a)
{
if (dim != a.dim) {
JSCerror("Incompatible matrix sizes in matrix operator +.");
exit(1);
}
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j) {
M[i][j] += a[i][j];
}
}
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator-= (const T& a)
{
for (int i = 0; i < dim; ++i) M[i][i] -= a;
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator-= (const SQMat<T>& a)
{
if (dim != a.dim) {
JSCerror("Incompatible matrix sizes in matrix operator +.");
exit(1);
}
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j) {
M[i][j] -= a[i][j];
}
}
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator*= (const T& a)
{
for (int i = 0; i < dim; ++i) for (int j = 0; j < dim; ++j) M[i][j] *= a;
return *this;
}
template <class T>
SQMat<T>& SQMat<T>::operator*= (const SQMat<T>& a)
{
if (dim != a.dim) {
JSCerror("Incompatible matrix sizes in matrix operator *.");
exit(1);
}
SQMat<T> leftarg(*this); // use copy constructor.
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j) {
M[i][j] = 0.0;
for (int k = 0; k < dim; ++k) {
M[i][j] += leftarg[i][k] * a[k][j];
}
}
}
return *this;
}
template <class T>
inline int SQMat<T>::size() const
{
return dim;
}
template <class T>
SQMat<T>::~SQMat()
{
if (M != 0) {
delete[] (M[0]);
delete[] (M);
}
}
//*****************************
template <class T>
class RecMat {
private:
int nrows;
int ncols;
T** M;
public:
RecMat (int Nrows, int Ncols); // initializes all elements of this n by n matrix to zero
RecMat (const T& a, int Nrows, int Ncols);
RecMat (const RecMat& rhs); // copy constructor
void Print ();
RecMat& operator= (const RecMat& rhs); // assignment
inline T* operator[] (const int i); // subscripting: pointer to row i
inline const T* operator[] (const int i) const;
inline int nr_rows() const;
inline int nr_cols() const;
~RecMat();
};
template <class T>
RecMat<T>::RecMat (int Nrows, int Ncols) : nrows(Nrows), ncols(Ncols), M(new T*[Nrows])
{
M[0] = new T[Nrows*Ncols];
for (int i = 1; i < Nrows; i++) M[i] = M[i-1] + Ncols;
for (int i = 0; i < Nrows; i++) for (int j = 0; j < Ncols; j++) M[i][j] = T(0);
}
template <class T>
RecMat<T>::RecMat (const T& a, int Nrows, int Ncols) : nrows(Nrows), ncols(Ncols), M(new T*[Nrows])
{
M[0] = new T[Nrows*Ncols];
for (int i = 1; i < Nrows; i++) M[i] = M[i-1] + Ncols;
for (int i = 0; i < Nrows; i++) for (int j = 0; j < Ncols; j++) {
if (i == j) M[i][i] = a;
else M[i][j] = T(0);
}
}
template <class T>
RecMat<T>::RecMat (const RecMat& rhs) : nrows(rhs.nrows), ncols(rhs.ncols), M(new T*[nrows])
{
int i,j;
M[0] = new T[nrows*ncols];
for (i = 1; i < nrows; i++) M[i] = M[i-1] + ncols;
for (i = 0; i < nrows; i++)
for (j = 0; j < ncols; j++) M[i][j] = rhs[i][j];
}
// operators
template <class T>
void RecMat<T>::Print ()
{
cout << endl;
for (int i = 0; i < nrows; ++i) {
for (int j = 0; j < ncols; ++j) cout << M[i][j] << " ";
cout << endl;
}
cout << endl;
}
template <class T>
RecMat<T>& RecMat<T>::operator= (const RecMat<T>& rhs)
{
if (this != &rhs) {
if (nrows != rhs.nrows || ncols != rhs.ncols) {
if (M != 0) {
delete[] (M[0]);
delete[] (M);
}
nrows = rhs.nrows;
ncols = rhs.ncols;
M = new T*[nrows];
M[0] = new T[nrows * ncols];
}
for (int i = 0; i < nrows; ++i)
for (int j = 0; j < ncols; ++j) M[i][j] = rhs[i][j];
}
return *this;
}
template <class T>
inline T* RecMat<T>::operator[] (const int i)
{
return M[i];
}
template <class T>
inline const T* RecMat<T>::operator[] (const int i) const
{
return M[i];
}
template <class T>
inline int RecMat<T>::nr_rows() const
{
return nrows;
}
template <class T>
inline int RecMat<T>::nr_cols() const
{
return ncols;
}
template <class T>
inline std::ostream& operator<< (std::ostream& s, const RecMat<T>& matrix)
{
for (int i = 0; i < matrix.nr_rows(); ++i) {
for (int j = 0; j < matrix.nr_cols(); ++j) s << matrix[i][j] << " ";
s << endl;
}
return (s);
}
template <class T>
RecMat<T>::~RecMat()
{
if (M != 0) {
delete[] (M[0]);
delete[] (M);
}
}
// TYPEDEFS:
typedef JSC::SQMat<DP> SQMat_DP;
typedef JSC::SQMat<complex<double> > SQMat_CX;
// FUNCTION DEFINITIONS
// Functions in src/MATRIX directory
DP det_LU (SQMat_DP a);
DP lndet_LU (SQMat_DP a);
complex<DP> lndet_LU_dstry (SQMat_DP& a);
complex<DP> det_LU_CX (SQMat_CX a);
complex<DP> lndet_LU_CX (SQMat_CX a);
complex<DP> lndet_LU_CX_dstry (SQMat_CX& a);
void eigsrt (Vect_DP& d, SQMat_DP& v);
void balanc (SQMat_DP& a);
void elmhes (SQMat_DP& a);
void gaussj (SQMat_DP& a, SQMat_DP& b);
void hqr (SQMat_DP& a, Vect_CX& wri);
void jacobi (SQMat_DP& a, Vect_DP& d, SQMat_DP& v, int& nrot);
void lubksb (SQMat_DP& a, Vect_INT& indx, Vect_DP& b);
void lubksb_CX (SQMat_CX& a, Vect_INT& indx, Vect_CX& b);
void ludcmp (SQMat_DP& a, Vect_INT& indx, DP& d);
void ludcmp_CX (SQMat_CX& a, Vect_INT& indx, DP& d);
DP pythag(DP a, DP b);
void tqli(Vect_DP& d, Vect_DP& e, SQMat_DP& z);
void tred2 (SQMat_DP& a, Vect_DP& d, Vect_DP& e);
} // namespace JSC
#endif

36
include/JSC_NRG.h Archivo normal
Ver fichero

@ -0,0 +1,36 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_NRG.h
Purpose: Declares NRG-related classes and functions.
***********************************************************/
#ifndef _NRG_
#define _NRG_
#include "JSC.h"
namespace JSC {
DP K_Weight_integrand (Vect_DP args); // weighing function for state selection
//void Select_States_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required, bool symmetric_states, int iKmod,
// int weighing_option, DP (*weight_integrand_fn) (Vect_DP), Vect_DP& args_to_weight_integrand);
void Select_States_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required, bool symmetric_states, int iKmod,
//int weighing_option, DP (*weight_integrand_fn) (Vect_DP), Vect_DP& args_to_weight_integrand)
int weighing_option, Vect<complex <DP> >& FT_of_potential);
void Build_DFF_Matrix_Block_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required, bool symmetric_states, int iKmod,
int weighing_option, int label_left_begin, int label_left_end, int label_right_begin, int label_right_end,
int block_option, DP* DFF_block_1, DP* DFF_block_2, Vect_DP Kweight);
}
#endif // _NRG_

463
include/JSC_ODSLF.h Archivo normal
Ver fichero

@ -0,0 +1,463 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: Heis.h
Purpose: Declares lattice spinless fermion classes and functions.
***********************************************************/
#ifndef _ODSLF_
#define _ODSLF_
#include "JSC.h"
namespace JSC {
//****************************************************************************
// Objects in class ODSLF_Base are a checked vector containing the number of rapidities of allowable types for a given state
class ODSLF_Base {
public:
int Mdown; // total number of down spins
Vect<int> Nrap; // Nrap[i] contains the number of rapidities of type i, i = 0, Nstrings - 1.
int Nraptot; // total number of strings in this state
Vect<DP> Ix2_infty; // Ix2_infty[i] contains the max of BAE function for the (half-)integer I[i], i = 0, Nstrings - 1.
Vect<int> Ix2_max; // Ix2_max[i] contains the integer part of 2*I_infty, with correct parity for base.
long long int id; // identification number
public:
ODSLF_Base ();
ODSLF_Base (const ODSLF_Base& RefBase); // copy constructor
ODSLF_Base (const Heis_Chain& RefChain, int M); // constructs configuration with all Mdown in one-string of +1 parity
ODSLF_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities); // sets to Nrapidities vector, and checks consistency
ODSLF_Base (const Heis_Chain& RefChain, long long int id_ref);
inline int& operator[] (const int i);
inline const int& operator[] (const int i) const;
ODSLF_Base& operator= (const ODSLF_Base& RefBase);
bool operator== (const ODSLF_Base& RefBase);
bool operator!= (const ODSLF_Base& RefBase);
void Compute_Ix2_limits(const Heis_Chain& RefChain); // computes the Ix2_infty and Ix2_max
void Scan_for_Possible_Types (Vect<long long int>& possible_type_id, int& nfound, int base_level, Vect<int>& Nexcitations);
Vect<long long int> Possible_Types (); // returns a vector of possible types
};
inline int& ODSLF_Base::operator[] (const int i)
{
return Nrap[i];
}
inline const int& ODSLF_Base::operator[] (const int i) const
{
return Nrap[i];
}
//****************************************************************************
// Objects in class ODSLF_Ix2_Config carry all the I's of a given state
class ODSLF_Ix2_Config {
//private:
public:
int Nstrings;
Vect<int> Nrap;
int Nraptot;
int** Ix2;
//Vect<Vect<int> > Ix2;
public:
ODSLF_Ix2_Config ();
ODSLF_Ix2_Config (const Heis_Chain& RefChain, int M); // constructor, puts I's to ground state
ODSLF_Ix2_Config (const Heis_Chain& RefChain, const ODSLF_Base& base); // constructor, putting I's to lowest-energy config
// consistent with Heis_Base configuration for chain RefChain
ODSLF_Ix2_Config& operator= (const ODSLF_Ix2_Config& RefConfig);
inline int* operator[] (const int i);
//inline Vect<int> operator[] (const int i);
inline const int* operator[] (const int i) const;
//inline const Vect<int> operator[] (const int i) const;
~ODSLF_Ix2_Config();
};
inline int* ODSLF_Ix2_Config::operator[] (const int i)
//inline Vect<int> Ix2_Config::operator[] (const int i)
{
return Ix2[i];
}
inline const int* ODSLF_Ix2_Config::operator[] (const int i) const
//inline const Vect<int> Ix2_Config::operator[] (const int i) const
{
return Ix2[i];
}
std::ostream& operator<< (std::ostream& s, const ODSLF_Ix2_Config& RefConfig);
//****************************************************************************
// Objects in class ODSLF_Lambda carry all rapidities of a state
class ODSLF_Lambda {
private:
int Nstrings;
Vect<int> Nrap;
int Nraptot;
DP** lambda;
//Vect<Vect<DP> > lambda;
public:
ODSLF_Lambda ();
ODSLF_Lambda (const Heis_Chain& RefChain, int M); // constructor, puts all lambda's to zero
ODSLF_Lambda (const Heis_Chain& RefChain, const ODSLF_Base& base); // constructor, putting I's to lowest-energy config
// consistent with Heis_Base configuration for chain RefChain
ODSLF_Lambda& operator= (const ODSLF_Lambda& RefConfig);
inline DP* operator[] (const int i);
//inline Vect<DP> operator[] (const int i);
inline const DP* operator[] (const int i) const;
//inline const Vect<DP> operator[] (const int i) const;
~ODSLF_Lambda();
};
inline DP* ODSLF_Lambda::operator[] (const int i)
//inline Vect<DP> Lambda::operator[] (const int i)
{
return lambda[i];
}
inline const DP* ODSLF_Lambda::operator[] (const int i) const
//inline const Vect<DP> Lambda::operator[] (const int i) const
{
return lambda[i];
}
//****************************************************************************
// Objects in class ODSLF_Ix2_Offsets carry Young tableau representations of the Ix2 configurations
class ODSLF_Ix2_Offsets {
public:
ODSLF_Base base;
Vect<Young_Tableau> Tableau; // vector of pointers to tableaux at each level
long long int type_id;
long long int id; // id number of offset
long long int maxid; // max id number allowable
public:
ODSLF_Ix2_Offsets ();
ODSLF_Ix2_Offsets (const ODSLF_Ix2_Offsets& RefOffset); // copy constructor
ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, long long int req_type_id);
ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, Vect<int> nparticles); // sets all tableaux to empty ones, with nparticles[] at each level
ODSLF_Ix2_Offsets& operator= (const ODSLF_Ix2_Offsets& RefOffset);
bool operator<= (const ODSLF_Ix2_Offsets& RefOffsets);
bool operator>= (const ODSLF_Ix2_Offsets& RefOffsets);
public:
void Set_to_id (long long int idnr);
void Compute_id ();
void Compute_type_id ();
public:
bool Add_Boxes_From_Lowest (int Nboxes, bool odd_sectors); // adds Nboxes in minimal energy config, all boxes in either even or odd sectors
};
inline long long int ODSLF_Ix2_Offsets_type_id (Vect<int>& nparticles)
{
long long int type_id_here = 0ULL;
for (int i = 0; i < nparticles.size(); ++i)
type_id_here += nparticles[i] * pow_ulli(10ULL, i);
return(type_id_here);
}
//****************************************************************************
// Objects in class ODSLF_Ix2_Offsets_List carry a vector of used Ix2_Offsets
class ODSLF_Ix2_Offsets_List {
public:
int ndef;
Vect<ODSLF_Ix2_Offsets> Offsets;
public:
ODSLF_Ix2_Offsets_List ();
ODSLF_Ix2_Offsets& Return_Offsets (ODSLF_Base& RefBase, Vect<int> nparticles); // returns the Ix2_Offsets corresponding to nparticles[]/base
ODSLF_Ix2_Offsets& Return_Offsets (ODSLF_Base& RefBase, long long int req_type_id);
};
//****************************************************************************
// Objects in class ODSLF_Bethe_State carry all information about an eigenstate
// Derived classes include XXZ_Bethe_State, XXX_Bethe_State, XXZ_gpd_Bethe_State
// These contain subclass-specific functions and data.
class ODSLF_Bethe_State {
public:
Heis_Chain chain;
ODSLF_Base base;
ODSLF_Ix2_Offsets offsets;
ODSLF_Ix2_Config Ix2;
ODSLF_Lambda lambda;
ODSLF_Lambda BE; // Bethe equation for relevant rapidity, in the form BE = theta - (1/N)\sum ... - \pi I/N = 0
DP diffsq; // sum of squares of rapidity differences in last iteration
int conv; // convergence status
int iter; // number of iterations necessary for convergence
int iter_Newton; // number of iterations necessary for convergence (Newton method)
DP E; // total energy
int iK; // K = 2.0*PI * iK/Nsites
DP K; // total momentum
DP lnnorm; // ln of norm of reduced Gaudin matrix
//long long int id;
//long long int maxid;
long long int base_id;
long long int type_id;
long long int id;
long long int maxid;
int nparticles;
public:
ODSLF_Bethe_State ();
ODSLF_Bethe_State (const ODSLF_Bethe_State& RefState); // copy constructor
ODSLF_Bethe_State (const ODSLF_Bethe_State& RefState, long long int type_id_ref); // new state with requested type_id
ODSLF_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
ODSLF_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& base); // constructor to lowest-energy config with base
ODSLF_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref);
virtual ~ODSLF_Bethe_State () {};
public:
int Charge () { return(base.Mdown); };
//void Set_I_Offset (const I_Offset& RefOffset); // sets the Ix2 to given offsets
void Set_Ix2_Offsets (const ODSLF_Ix2_Offsets& RefOffset); // sets the Ix2 to given offsets
void Set_to_id (long long int id_ref);
void Set_to_id (long long int id_ref, ODSLF_Bethe_State& RefState);
int Nparticles (); // counts the number of particles in state once Ix2 offsets set (so type_id is correctly set)
bool Check_Symmetry (); // checks whether the I's are symmetrically distributed
void Compute_diffsq (); // \sum BE[j][alpha]^2
void Iterate_BAE (); // Finds new set of lambda[j][alpha] from previous one by simple iteration
void Iterate_BAE_Newton (); // Finds new set of lambda[j][alpha] from previous one by a Newton step
void Find_Rapidities (bool reset_rapidities); // Finds the rapidities
void Find_Rapidities_Twisted (bool reset_rapidities, DP twist); // Finds the rapidities with twist added to RHS of logBE
void BAE_smackdown (DP max_allowed);
void Solve_BAE_smackdown (DP max_allowed, int maxruns);
void Solve_BAE (int j, int alpha, DP req_prec, int itermax);
void Solve_BAE_interp (DP interp_prec, int max_iter_interp);
void Solve_BAE_straight_iter (DP interp_prec, int max_iter_interp);
void Solve_BAE_Newton (DP Newton_prec, int max_iter_Newton);
void Compute_lnnorm ();
void Compute_Momentum ();
void Compute_All (bool reset_rapidities); // solves BAE, computes E, K and lnnorm
bool Boost_Momentum (int iKboost);
// Virtual functions, all defined in the derived classes
public:
virtual void Set_Free_lambdas() { JSCerror("ODSLF_Bethe_State::..."); } // sets the rapidities to solutions of BAEs without scattering terms
virtual bool Check_Admissibility(char option) { JSCerror("ODSLF_Bethe_State::..."); return(false); }
// verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
virtual void Compute_BE (int j, int alpha) { JSCerror("ODSLF_Bethe_State::..."); }
virtual void Compute_BE () { JSCerror("ODSLF_Bethe_State::..."); }
virtual DP Iterate_BAE(int i, int alpha) { JSCerror("ODSLF_Bethe_State::..."); return(0.0);}
virtual bool Check_Rapidities() { JSCerror("ODSLF_Bethe_State::..."); return(false); }
virtual void Compute_Energy () { JSCerror("ODSLF_Bethe_State::..."); }
virtual void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red) { JSCerror("ODSLF_Bethe_State::..."); }
};
inline bool Force_Descent (char whichDSF, ODSLF_Bethe_State& ScanState, ODSLF_Bethe_State& RefState, int desc_type_required, int iKmod, DP Chem_Pot)
{
JSCerror("Need to implement Force_Descent properly for ODSLF.");
bool force_descent = false;
// Force descent if energy of ScanState is lower than that of RefState
if (ScanState.E - RefState.E - (ScanState.base.Mdown - RefState.base.Mdown) < 0.0) return(true);
/*
// We force descent if
// 1) - there exists a higher string whose quantum number is still on 0
// AND - there is at most a single particle-hole in the 0 base level
// AND - either the particle or the hole hasn't yet moved.
if (RefState.base_id/100000LL > 0) { // there is a higher string
int type0 = RefState.type_id % 10000;
if (type0 == 0
|| type0 == 101 && RefState.offsets.Tableau[0].id * RefState.offsets.Tableau[2].id == 0LL
|| type0 == 110 && RefState.offsets.Tableau[1].id * RefState.offsets.Tableau[2].id == 0LL
|| type0 == 1001 && RefState.offsets.Tableau[0].id * RefState.offsets.Tableau[3].id == 0LL
|| type0 == 1010 && RefState.offsets.Tableau[1].id * RefState.offsets.Tableau[3].id == 0LL) // single p-h pair in base level 0
for (int j = 1; j < RefState.chain.Nstrings; ++j) {
if (RefState.base[j] == 1 && RefState.Ix2[j][0] == 0) {
force_descent = true;
}
}
}
*/
// Force descent if quantum nr distribution is symmetric:
if (RefState.Check_Symmetry()) force_descent = true;
return(force_descent);
}
std::ostream& operator<< (std::ostream& s, const ODSLF_Bethe_State& state);
//****************************************************************************
// Objects in class XXZ_Bethe_State carry all extra information pertaining to XXZ gapless
class ODSLF_XXZ_Bethe_State : public ODSLF_Bethe_State {
public:
ODSLF_Lambda sinhlambda;
ODSLF_Lambda coshlambda;
ODSLF_Lambda tanhlambda;
public:
ODSLF_XXZ_Bethe_State ();
ODSLF_XXZ_Bethe_State (const ODSLF_XXZ_Bethe_State& RefState); // copy constructor
ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& base); // constructor to lowest-energy config with base
ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with bas
public:
ODSLF_XXZ_Bethe_State& operator= (const ODSLF_XXZ_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
void Compute_sinhlambda();
void Compute_coshlambda();
void Compute_tanhlambda();
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
bool Check_Rapidities(); // checks that all rapidities are not nan
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXZ specific functions:
public:
};
//****************************************************************************
/*
// Objects in class ODSLF_XXX_Bethe_State carry all extra information pertaining to XXX antiferromagnet
class ODSLF_XXX_Bethe_State : public ODSLF_Bethe_State {
public:
ODSLF_XXX_Bethe_State ();
ODSLF_XXX_Bethe_State (const ODSLF_XXX_Bethe_State& RefState); // copy constructor
ODSLF_XXX_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
ODSLF_XXX_Bethe_State (const Heis_Chain& RefChain, const ODSLF__Base& base); // constructor to lowest-energy config with base
ODSLF_XXX_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with base
public:
ODSLF_XXX_Bethe_State& operator= (const ODSLF_XXX_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
bool Check_Rapidities(); // checks that all rapidities are not nan
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXX specific functions
public:
bool Check_Finite_rap ();
};
*/
//****************************************************************************
/*
// Objects in class ODSLF_XXZ_gpd_Bethe_State carry all extra information pertaining to XXZ gapped antiferromagnets
class ODSLF_XXZ_gpd_Bethe_State : public ODSLF__Bethe_State {
public:
Lambda sinlambda;
Lambda coslambda;
Lambda tanlambda;
public:
ODSLF_XXZ_gpd_Bethe_State ();
ODSLF_XXZ_gpd_Bethe_State (const ODSLF_XXZ_gpd_Bethe_State& RefState); // copy constructor
ODSLF_XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, int M); // constructor to ground-state configuration
ODSLF_XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& base); // constructor to lowest-energy config with base
ODSLF_XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref); // constructor to lowest-energy config with base
public:
ODSLF_XXZ_gpd_Bethe_State& operator= (const ODSLF_XXZ_gpd_Bethe_State& RefState);
public:
void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
void Compute_sinlambda();
void Compute_coslambda();
void Compute_tanlambda();
int Weight(); // weight function for contributions cutoff
bool Check_Admissibility(char option); // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
void Compute_BE (int j, int alpha);
void Compute_BE ();
DP Iterate_BAE(int i, int j);
void Iterate_BAE_Newton();
bool Check_Rapidities(); // checks that all rapidities are not nan and are in interval ]-PI/2, PI/2]
void Compute_Energy ();
//void Compute_Momentum ();
void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
// XXZ_gpd specific functions
public:
};
*/
//***********************************************
// Function declarations
/*
// in M_vs_H.cc
DP Ezero (DP Delta, int N, int M);
DP H_vs_M (DP Delta, int N, int M);
DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref);
int M_vs_H (DP Delta, int N, DP HZ);
DP X_avg (char xyorz, DP Delta, int N, int M);
*/
DP Chemical_Potential (const ODSLF_Bethe_State& RefState);
//DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& RefState, DP Chem_Pot, bool fixed_iK, int iKneeded);
DP Sumrule_Factor (char whichDSF, ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
void Evaluate_F_Sumrule (string prefix, char whichDSF, const ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B);
complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B);
//DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, ODSLF_XXZ_Bethe_State& LeftState,
// ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, ODSLF_XXZ_Bethe_State& LeftState,
ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
} // namespace JSC
#endif

1263
include/JSC_Scan.h Archivo normal

La diferencia del archivo ha sido suprimido porque es demasiado grande Cargar Diff

207
include/JSC_Spec_Fns.h Archivo normal
Ver fichero

@ -0,0 +1,207 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_Spec_Fns.h
Purpose: Defines special math functions.
***********************************************************/
#ifndef _JSC_SPEC_FNS_H_
#define _JSC_SPEC_FNS_H_
#include "JSC.h"
using namespace std;
namespace JSC {
inline DP Cosine_Integral (DP x)
{
// Returns the Cosine integral -\int_x^\infty dt \frac{\cos t}{t}
// Refer to GR[6] 8.23
if (x <= 0.0) {
cout << "Cosine_Integral called with real argument " << x << " <= 0, which is ill-defined because of the branch cut." << endl;
JSCerror("");
}
else if (x < 15.0) { // Use power series expansion
// Ci (x) = gamma + \ln x + \sum_{n=1}^\infty (-1)^n x^{2n}/(2n (2n)!).
int n = 1;
DP minonetothen = -1.0;
DP logxtothetwon = 2.0 * log(x);
DP twologx = 2.0 * log(x);
DP logtwonfact = log(2.0);
DP series = minonetothen * exp(logxtothetwon - log(2.0 * n) - logtwonfact);
DP term_n;
do {
n += 1;
minonetothen *= -1.0;
logxtothetwon += twologx;
logtwonfact += log((2.0 * n - 1.0) * 2.0 * n);
term_n = minonetothen * exp(logxtothetwon - log(2.0 * n) - logtwonfact);
series += term_n;
} while (fabs(term_n) > 1.0e-16);
/*
// For improved convergence we pair terms up, DOESN'T WORK WELL
// Ci (x) = gamma + \ln x - \sum{n = 1, 3, 5, ...} \frac{x^{2n}}{2n (2n)!} ( 1 - \frac{n}{n+1} \frac{x^2}{(2n+1)(2n+2)} )
int n = 1;
DP logxtothetwon = 2.0 * log(x);
DP logtwon = log(2.0);
DP logtwonfact = log(2.0);
DP xsq = x*x;
DP series = exp(logxtothetwon - logtwon - logtwonfact) * (1 - xsq/((2.0 * n + 1.0) * (2.0 * n + 2.0) * (1.0 + 1.0/n)));
DP term_n;
DP twologx = 2.0 * log(x);
do {
n += 2;
logxtothetwon += twologx;
logtwonfact += log((2.0 * n - 1.0) * 2.0 * n);
term_n = exp(logxtothetwon - log(2.0 * n) - logtwonfact) * (1 - xsq/((2.0 * n + 1.0) * (2.0 * n + 2.0) * (1.0 + 1.0/n)));;
series += term_n;
} while (fabs(term_n) > 1.0e-16);
*/
return(Euler_Mascheroni + log(x) + series);
}
else { // Use high x power series
// Ci (x) = \frac{\sin x}{x} \sum_{n=0}^\infty (-1)^n (2n)! x^{-2n} - \frac{\cos x}{x} \sum_{n=0}^\infty (-1)^n (2n+1)! x^{-2n-1}
int n = 0;
DP minonetothen = 1.0;
DP logxtothetwon = 0.0;
DP logxtothetwonplus1 = log(x);
DP twologx = 2.0 * log(x);
DP logtwonfact = 0.0;
DP logtwonplus1fact = 0.0;
DP series1 = minonetothen * exp(logtwonfact - logxtothetwon);
DP series2 = minonetothen * exp(logtwonplus1fact - logxtothetwonplus1);
do {
n += 1;
minonetothen *= -1.0;
logxtothetwon += twologx;
logxtothetwonplus1 += twologx;
logtwonfact += log((2.0 * n - 1.0) * 2.0 * n);
logtwonplus1fact += log(2.0 * n * (2.0 * n + 1));
series1 += minonetothen * exp(logtwonfact - logxtothetwon);
series2 += minonetothen * exp(logtwonplus1fact - logxtothetwonplus1);
} while (n < 12);
return((sin(x)/x) * series1 - (cos(x)/x) * series2);
}
return(log(-1.0));
}
/*********** Jacobi Theta functions *********/
inline DP Jacobi_Theta_1_q (DP u, DP q) {
// Uses the summation formula.
// theta_1 (x) = 2 \sum_{n=1}^\infty (-1)^{n+1} q^{(n-1/2)^2} \sin (2n-1)u
// in which q is the nome. (GR 8.180.1)
// We always evaluate to numerical accuracy.
if (q >= 1.0) JSCerror("Jacobi_Theta_1_q function called with q > 1.");
DP answer = 0.0;
DP contrib = 0.0;
DP qtonminhalfsq = pow(q, 0.25); // this will be q^{(n-1/2)^2}
DP qtotwon = pow(q, 2.0); // this will be q^{2n}
DP qsq = q*q;
int n = 1;
do {
contrib = (n % 2 ? 2.0 : -2.0) * qtonminhalfsq * sin((2.0*n - 1.0)*u);
answer += contrib;
qtonminhalfsq *= qtotwon;
qtotwon *= qsq;
n++;
//cout << "\t\tn = " << n << "\tanswer = " << answer << "\tcontrib = " << contrib << "\tqtonminhalfsq = " << qtonminhalfsq << "\tqtotwon = " << qtotwon << endl;
} while (fabs(contrib/answer) > MACHINE_EPS);
//cout << "\t\tJacobi_Theta_1: used " << n << " iterations." << "\tanswer = " << answer << "\tcontrib = " << contrib << "\tqtonminhalfsq = " << qtonminhalfsq << "\tqtotwon = " << qtotwon << endl;
return(answer);
}
inline complex<DP> ln_Jacobi_Theta_1_q (complex<DP> u, complex<DP> q) {
// This uses the product representation
// \theta_1 (x) = 2 q^{1/4} \sin{u} \prod_{n=1}^\infty (1 - 2 q^{2n} \cos 2u + q^{4n}) (1 - q^{2n})
// (GR 8.181.2)
complex<DP> contrib = 0.0;
complex<DP> qtotwon = q*q; // this will be q^{2n}
complex<DP> qsq = q*q;
complex<DP> twocos2u = 2.0 * cos(2.0*u);
int n = 1;
complex<DP> answer = log(2.0 * sin(u)) + 0.25 * log(q);
do {
contrib = log((1.0 - twocos2u * qtotwon + qtotwon * qtotwon) * (1.0 - qtotwon));
answer += contrib;
qtotwon *= qsq;
n++;
} while (abs(contrib) > 1.0e-12);
return(answer);
}
/************ Barnes function ************/
inline DP ln_Gamma_for_Barnes_G_RE (Vect_DP args)
{
return(real(ln_Gamma(complex<double>(args[0]))));
}
inline DP ln_Barnes_G_RE (DP z)
{
// Implementation according to equation (28) of 2004_Adamchik_CPC_157
// Restricted to real arguments.
Vect_DP args (0.0, 2);
DP req_rel_prec = 1.0e-6;
DP req_abs_prec = 1.0e-6;
int max_nr_pts = 10000;
Integral_result integ_ln_Gamma = Integrate_optimal (ln_Gamma_for_Barnes_G_RE, args, 0, 0.0, z - 1.0, req_rel_prec, req_abs_prec, max_nr_pts);
return(0.5 * (z - 1.0) * (2.0 - z + logtwoPI) + (z - 1.0) * real(ln_Gamma(complex<double>(z - 1.0))) - integ_ln_Gamma.integ_est);
}
} // namespace JSC
#endif // _JS_SPEC_FNS_H_

47
include/JSC_State_Ensemble.h Archivo normal
Ver fichero

@ -0,0 +1,47 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_State_Ensemble.h
Purpose: Define state ensembles.
***********************************************************/
#ifndef _ENS_
#define _ENS_
#include "JSC.h"
namespace JSC {
struct LiebLin_Diagonal_State_Ensemble {
int nstates;
Vect<LiebLin_Bethe_State> state;
Vect<DP> weight;
LiebLin_Diagonal_State_Ensemble ();
LiebLin_Diagonal_State_Ensemble (const LiebLin_Bethe_State& RefState, int nstates_req);
//LiebLin_Diagonal_State_Ensemble (const LiebLin_Bethe_State& RefState, int nstates_req, const Vect<DP>& weight_ref);
//LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho, int nstates_req);
LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho);
LiebLin_Diagonal_State_Ensemble& operator= (const LiebLin_Diagonal_State_Ensemble& rhs);
void Load (DP c_int, DP L, int N, const char* ensfile_Cstr);
void Save (const char* ensfile_Cstr);
};
//LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT, int nstates_req);
LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT);
} // namespace JSC
#endif

147
include/JSC_TBA.h Archivo normal
Ver fichero

@ -0,0 +1,147 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS. library.
Copyright (c).
-----------------------------------------------------------
File: JSC_TBA.h
Purpose: Thermodynamic Bethe Ansatz general functions
***********************************************************/
#ifndef _TBA_
#define _TBA_
#include "JSC.h"
namespace JSC {
struct Root_Density {
int Npts; // how many points are used to describe each function
DP lambdamax; // what the largest rapidity is
Vect_DP lambda; // rapidity vector
Vect_DP dlambda; // differential element
Vect_DP value; // the root density itself
Vect_DP prev_value; // results of previous iteration
DP diff; // relative differences with previous iteration
bool value_infty_set; // boolean, true if asymptotic value set
DP value_infty; // asymptotic value, computed analytically
Root_Density ();
Root_Density (int Npts_ref, DP lambdamax_ref);
Root_Density& operator= (const Root_Density& RefDensity);
void Save (const char* outfile_Cstr);
DP Return_Value (DP lambda_ref); // evaluates the function for any argument using linear interpolation
void Set_Asymptotics (DP value_infty_ref); // sets value for lambda >= lambdamax
Root_Density Compress_and_Match_Densities (DP comp_factor); // returns a Root_Density with fewer points
};
struct Root_Density_Set {
int ntypes;
Vect<Root_Density> epsilon;
int Npts_total; // sum of all Npts of epsilon's
DP diff; // sum of diff's of the epsilon's
Root_Density_Set ();
Root_Density_Set (int ntypes_ref, int Npts_ref, DP lambdamax_ref);
Root_Density_Set (int ntypes_ref, Vect_INT Npts_ref, Vect_DP lambdamax_ref);
Root_Density_Set& operator= (const Root_Density_Set& RefSet);
void Insert_new_function (DP asymptotic_value);
void Extend_limits (Vect<bool> need_to_extend_limit);
void Insert_new_points (Vect<Vect<bool> > need_new_point_around);
DP Return_Value (int n_ref, DP lambda_ref); // returns a value, no matter what.
Root_Density_Set Return_Compressed_and_Matched_Set (DP comp_factor);
void Match_Densities (Root_Density_Set& RefSet);
void Save (const char* outfile_Cstr);
};
struct LiebLin_TBA_Solution {
DP c_int;
DP mu;
DP kBT;
DP nbar;
DP ebar; // mean energy, \int d\lambda \lambda^2 \rho (\lambda)
DP sbar; // entropy per unit length
Root_Density epsilon;
Root_Density depsilon_dmu;
Root_Density rho;
Root_Density rhoh;
LiebLin_TBA_Solution (DP c_int_ref, DP mu_ref, DP kBT_ref, DP req_diff, int Max_Secs);
};
// Functions defined in TBA_LiebLin.cc
Root_Density LiebLin_rho_GS (DP c_int, DP k_F, DP lambdamax, int Npts, DP req_prec);
DP Density_GS (Root_Density& rho_GS);
DP k_F_given_n (DP c_int, DP n, DP lambdamax, int Npts, DP req_prec);
Root_Density LiebLin_Z_GS (DP c_int, DP k_F, DP lambdamax, int Npts, DP req_prec);
Root_Density LiebLin_Fbackflow_GS (DP c_int, DP k_F, DP lambdamax, DP lambda, int Npts, DP req_prec);
// epsilon for a given mu:
Root_Density LiebLin_epsilon_TBA (DP c_int, DP mu, DP kBT, DP req_diff, int Max_Secs);
// depsilon/dmu for a given mu:
Root_Density LiebLin_depsilon_dmu_TBA (DP c_int, DP mu, DP kBT, DP req_diff, int Max_Secs, const Root_Density& epsilon);
Root_Density LiebLin_rho_TBA (DP kBT, const Root_Density& epsilon, const Root_Density& depsilon_dmu);
Root_Density LiebLin_rhoh_TBA (DP kBT, const Root_Density& epsilon, const Root_Density& depsilon_dmu);
DP LiebLin_nbar_TBA (const Root_Density& rho);
DP LiebLin_ebar_TBA (const Root_Density& rho);
DP LiebLin_sbar_TBA (const Root_Density& rho, const Root_Density& rhoh);
LiebLin_TBA_Solution LiebLin_TBA_Solution_fixed_nbar (DP c_int, DP nbar_required, DP kBT, DP req_diff, int Max_Secs);
LiebLin_TBA_Solution LiebLin_TBA_Solution_fixed_nbar_ebar (DP c_int, DP nbar_required, DP ebar_required, DP req_diff, int Max_Secs);
LiebLin_Bethe_State Discretized_LiebLin_Bethe_State (DP c_int, DP L, int N, const Root_Density& rho);
// Functions defined in TBA_XXZ.cc
DP XXZ_phi1_kernel (DP zeta, DP lambda);
DP XXZ_phi2_kernel (DP zeta, DP lambda);
DP XXZ_a1_kernel (DP sinzeta, DP coszeta, DP lambda);
DP XXZ_da1dlambda_kernel (DP sinzeta, DP coszeta, DP lambda);
DP XXZ_a2_kernel (DP sin2zeta, DP cos2zeta, DP lambda);
Root_Density XXZ_rhotot_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
DP Return_GS_Sz_tot_value (DP B, Root_Density& rhotot_GS);
Root_Density XXZ_eps_GS (DP Delta, DP Hz, DP lambdamax, int Npts, DP req_prec);
Root_Density XXZ_depsdlambda_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
Root_Density XXZ_b2BB_lambda_B (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
Root_Density XXZ_b2BB_lambda_lambdap (DP Delta, DP B, DP lambdap, DP lambdamax, int Npts, DP req_prec);
Root_Density XXZ_Kbackflow_GS (DP Delta, DP B, DP lambdamax, DP lambda_p, DP lambda_h, int Npts, DP req_prec);
Root_Density XXZ_Fbackflow_GS (DP Delta, DP B, DP lambdamax, DP lambda_p, DP lambda_h, int Npts, DP req_prec);
Root_Density XXZ_Z_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
//void XXZ_Compare_Lattice_and_Continuum_Backflows_base_1010 (DP Delta, int N, int M, long long int id);
// Defined in TBA_2CBG.cc:
struct TBA_Data_2CBG {
DP c_int;
DP mu;
DP Omega;
DP kBT;
DP f; // Gibbs free energy
DP n1; // first population
DP n2; // second population
};
// Defined in src/TBA_2CBG.cc:
TBA_Data_2CBG Solve_2CBG_TBAE_via_refinements (DP c_int, DP mu, DP Omega, DP kBT, int Max_Secs, bool Save_data);
// Defined in src/TBA_2CBG.cc:
void Scan_2CBG_TBAE (DP c_int, DP mu_min, DP mu_max, int Nmu, DP Omega_min, DP Omega_max, int NOmega,
DP kBT_min, DP kBT_max, int NkBT, int Max_Secs);
} // namespace JSC
#endif

472
include/JSC_Vect.h Archivo normal
Ver fichero

@ -0,0 +1,472 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS++ library.
Copyright (c)
-----------------------------------------------------------
File: JSC_Vect.h
Purpose: Declares vector class.
***********************************************************/
#ifndef _JSC_VECT_
#define _JSC_VECT_
namespace JSC {
template <class T>
class Vect {
private:
int dim;
T* V;
public:
Vect();
explicit Vect (int N);
Vect (const T& a, int N); // initialize all N elements are a
Vect (const T* a, int N); // initialize to array
Vect (const Vect& rhs); // Copy constructor
Vect& operator= (const Vect& rhs); // assignment
Vect& operator= (const T& a); // assign a to all elements
inline T& operator[] (const int i);
inline const T& operator[] (const int i) const;
Vect& operator+= (const Vect& rhs);
Vect& operator-= (const Vect& rhs);
bool operator== (const Vect& rhs); // checks equality of size and of all elements
bool operator!= (const Vect& rhs); // checks inequality
bool Append (const T& rhs); // appends rhs to the vector
bool Append (const Vect& rhs); // appends rhs to the vector
bool Increase_Size (int nr_to_add); // resizes the array to accommodate nr_to_add more entries
bool Increase_Size (int nr_to_add, T setval); // resizes the array to accommodate nr_to_add more entries
inline int size() const;
inline double norm() const; // returns norm of vector
inline T max() const; // returns maximal value
inline T min() const; // returns maximal value
inline T sum() const; // returns sum of all elements
inline bool includes(T check) const; // whether check == one of the elements or not
void QuickSort (int l, int r);
void QuickSort (Vect<int>& index, int l, int r);
void QuickSort ();
void QuickSort (Vect<int>& index);
~Vect();
};
template <class T>
Vect<T>::Vect() : dim(0), V(0) {}
template <class T>
Vect<T>::Vect (int N) : dim(N), V(new T[N]) {}
template <class T>
Vect<T>::Vect (const T& a, int N) : dim(N), V(new T[N])
{
for (int i = 0; i < N; ++i) V[i] = a;
}
template <class T>
Vect<T>::Vect (const T* a, int N) : dim(N), V(new T[N])
{
for (int i = 0; i < N; ++i) V[i] = *a++;
}
template <class T>
Vect<T>::Vect (const Vect<T>& rhs) : dim(rhs.dim), V(new T[dim])
{
for (int i = 0; i < dim; ++i) V[i] = rhs[i];
}
template <class T>
Vect<T>& Vect<T>::operator= (const Vect<T>& rhs)
{
if (this != &rhs) {
if (dim != rhs.dim) {
if (V != 0) delete[] V;
dim = rhs.dim;
V = new T[dim];
}
for (int i = 0; i < dim; ++i) V[i] = rhs[i];
}
return *this;
}
template <class T>
Vect<T>& Vect<T>::operator= (const T& a)
{
for (int i = 0; i < dim; ++i) V[i] = a;
return *this;
}
template <class T>
inline T& Vect<T>::operator[] (const int i)
{
return V[i];
}
template <class T>
inline const T& Vect<T>::operator[] (const int i) const
{
return V[i];
}
template <class T>
Vect<T>& Vect<T>::operator+= (const Vect<T>& rhs)
{
for (int i = 0; i < dim; ++i) V[i] += rhs[i];
return *this;
}
template <class T>
Vect<T>& Vect<T>::operator-= (const Vect<T>& rhs)
{
for (int i = 0; i < dim; ++i) V[i] -= rhs[i];
return *this;
}
template <class T>
bool Vect<T>::operator== (const Vect<T>& rhs)
{
bool answer = ((*this).size() == rhs.size());
if (answer) {
for (int i = 0; i < dim; ++i) answer = (answer && (V[i] == rhs[i]));
}
return answer;
}
template <class T>
bool Vect<T>::operator!= (const Vect<T>& rhs)
{
return(!((*this) == rhs));
}
template <class T>
bool Vect<T>::Append (const Vect<T>& rhs) // appends rhs to the vector
{
T* newvect = new T[dim + rhs.size()];
for (int i = 0; i < dim; ++i) newvect[i] = V[i];
for (int i = 0; i < rhs.size(); ++i) newvect[i+ dim] = rhs[i];
dim += rhs.size();
delete[] V;
V = new T[dim];
for (int i = 0; i < dim; ++i) V[i] = newvect[i];
delete[] newvect;
return(true);
}
template <class T>
bool Vect<T>::Append (const T& rhs) // appends rhs to the vector
{
T* newvect = new T[dim + 1];
for (int i = 0; i < dim; ++i) newvect[i] = V[i];
newvect[dim] = rhs;
dim += 1;
delete[] V;
V = new T[dim];
for (int i = 0; i < dim; ++i) V[i] = newvect[i];
delete[] newvect;
return(true);
}
template <class T>
bool Vect<T>::Increase_Size (int nr_to_add) // resizes the array to accommodate nr_to_add more entries
{
int resized_dim = dim + nr_to_add;
T* resized_vect = new T[resized_dim];
for (int i = 0; i < dim; ++i) resized_vect[i] = V[i];
for (int i = dim; i < resized_dim; ++i) resized_vect[i] = T(0);
dim = resized_dim;
delete[] V;
V = new T[dim];
for (int i = 0; i < dim; ++i) V[i] = resized_vect[i];
delete[] resized_vect;
return(true);
}
template <class T>
bool Vect<T>::Increase_Size (int nr_to_add, T setval) // resizes the array to accommodate nr_to_add more entries
{
int resized_dim = dim + nr_to_add;
T* resized_vect = new T[resized_dim];
for (int i = 0; i < dim; ++i) resized_vect[i] = V[i];
for (int i = dim; i < resized_dim; ++i) resized_vect[i] = setval;
dim = resized_dim;
delete[] V;
V = new T[dim];
for (int i = 0; i < dim; ++i) V[i] = resized_vect[i];
delete[] resized_vect;
return(true);
}
template <class T>
inline int Vect<T>::size() const
{
return dim;
}
template <class T>
inline double Vect<T>::norm () const
{
double normsq = 0.0;
for (int i = 0; i < dim; ++i) normsq += abs(V[i]) * abs(V[i]);
return sqrt(normsq);
}
template <>
inline double Vect<double>::norm () const
{
double normsq = 0.0;
for (int i = 0; i < dim; ++i) normsq += V[i] * V[i];
return(sqrt(normsq));
}
template <>
inline double Vect<complex<double> >::norm () const
{
double normsq = 0.0;
for (int i = 0; i < dim; ++i) normsq += std::norm(V[i]);
return(sqrt(normsq));
}
template <class T>
inline T Vect<T>::max() const
{
T maxval = V[0];
for (int i = 0; i < dim; ++i) if (V[i] > maxval) maxval = V[i];
return maxval;
}
template <class T>
inline T Vect<T>::min() const
{
T minval = V[0];
for (int i = 0; i < dim; ++i) if (V[i] < minval) minval = V[i];
return minval;
}
template <class T>
inline T Vect<T>::sum() const
{
T total = T(0);
for (int i = 0; i < dim; ++i) total += V[i];
return total;
}
template <class T>
inline bool Vect<T>::includes (T check) const
{
int index = 0;
while (index < dim && V[index] != check) index++;
return(index < dim);
}
/*
template <class T>
void Vect<T>::QuickSort (int l, int r)
{
//cout << "QuickSort called for l = " << l << "\t r = " << r << endl;
//cout << (*this) << endl;
//for (int ih = l; ih <= r; ++ih) cout << setprecision(16) << "ih = " << ih << "\tV[ih] = " << V[ih] << endl;
static T m;
static int j;
int i;
if (r > l) {
m = V[r]; i = l-1; j = r;
for (;;) {
while (V[++i] < m);
while (V[--j] > m);
if (i >= j) break;
std::swap(V[i], V[j]);
}
std::swap(V[i], V[r]);
(*this).QuickSort(l, i-1);
(*this).QuickSort(i+1, r);
}
}
*/
/*
template <class T>
void Vect<T>::QuickSort (int l, int r)
{
// My own version of QuickSort: add sentinels on left and right
if (r > l) {
int s = l + (r-l)/2; // central element index
// Rearrange so that V[l] <= V[s] <= V[r] (sentinels on left and right)
if (V[l] > V[r]) std::swap(V[l],V[r]);
if (V[s] > V[r]) std::swap(V[s],V[r]);
if (V[l] > V[s]) std::swap(V[l],V[s]);
m = V[s]; i = l-1; j = r;
//m = V[r]; i = l-1; j = r;
for (;;) {
while (V[i] < m) i++;
while (V[j] > m) j--;
if (i >= j) break;
std::swap(V[i], V[j]); // restart from indices i and j just used, in case one is pivot
}
//std::swap(V[i], V[r]);
(*this).QuickSort(l, i-1);
(*this).QuickSort(i+1, r);
}
}
*/
template <class T>
void Vect<T>::QuickSort (int l, int r)
{
int i = l, j = r;
T pivot = V[l + (r-l)/2];
while (i <= j) {
while (V[i] < pivot) i++;
while (V[j] > pivot) j--;
if (i <= j) {
std::swap(V[i],V[j]);
i++;
j--;
}
};
if (l < j) (*this).QuickSort(l, j);
if (i < r) (*this).QuickSort(i, r);
}
template <class T>
void Vect<T>::QuickSort ()
{
if ((*this).size() > 1) (*this).QuickSort (0, (*this).size() - 1);
}
/*
template <class T>
void Vect<T>::QuickSort (Vect<int>& index, int l, int r)
{
if (index.size() != (*this).size()) {
cout << (*this).size() << "\t" << index.size() << endl;
JSCerror("Wrong dim for index in Vect QuickSort.");
}
static T m;
static int j;
int i;
if (r > l) {
m = V[r]; i = l-1; j = r;
for (;;) {
while (V[++i] < m);
while (V[--j] > m);
if (i >= j) break;
std::swap(V[i], V[j]);
std::swap(index[i], index[j]);
}
std::swap(V[i], V[r]);
std::swap(index[i], index[r]);
(*this).QuickSort(index, l, i-1);
(*this).QuickSort(index, i+1, r);
}
}
*/
/*
template <class T>
void Vect<T>::QuickSort (Vect<int>& index, int l, int r)
{
// My own version of QuickSort:
if (r > l) {
int s = l + (r-l)/2; // central element index
// Rearrange so that V[l] <= V[s] <= V[r] (sentinels on left and right)
if (V[l] > V[r]) std::swap(V[l],V[r]);
if (V[s] > V[r]) std::swap(V[s],V[r]);
if (V[l] > V[s]) std::swap(V[l],V[s]);
m = V[s]; i = l-1; j = r+1;
for (;;) {
while (V[++i] < m);
while (V[--j] > m);
if (i >= j) break;
std::swap(index[i], index[j]);
std::swap(V[i--], V[j++]); // restart from indices i and j just used, in case one is pivot
}
(*this).QuickSort(index, l, i-1);
(*this).QuickSort(index, i+1, r);
}
}
*/
template <class T>
void Vect<T>::QuickSort (Vect<int>& index, int l, int r)
{
int i = l, j = r;
T pivot = V[l + (r-l)/2];
while (i <= j) {
while (V[i] < pivot) i++;
while (V[j] > pivot) j--;
if (i <= j) {
std::swap(V[i],V[j]);
std::swap(index[i],index[j]);
i++;
j--;
}
};
if (l < j) (*this).QuickSort(index, l, j);
if (i < r) (*this).QuickSort(index, i, r);
}
template <class T>
void Vect<T>::QuickSort (Vect<int>& index)
{
if (index.size() != (*this).size()) JSCerror("Wrong dim for index in Vect QuickSort.");
(*this).QuickSort (index, 0, (*this).size() - 1);
}
template <class T>
inline std::ostream& operator<< (std::ostream& s, const Vect<T>& vector)
{
for (int i = 0; i < vector.size() - 1; ++i) s << vector[i] << " ";
if (vector.size() >= 1) s << vector[vector.size() - 1];
return (s);
}
template <class T>
Vect<T>::~Vect<T>()
{
if (V != 0) delete[] V;
}
// TYPEDEFS
typedef JSC::Vect<int> Vect_INT;
typedef JSC::Vect<double> Vect_DP;
typedef JSC::Vect<complex<double> > Vect_CX;
} // namespace JSC
#endif

139
include/JSC_XXX_h0.h Archivo normal
Ver fichero

@ -0,0 +1,139 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_XXX_h0.h
Purpose: Declares classes for XXX in zero field: Uq(sl(2)) stuff.
***********************************************************/
#ifndef _XXX_h0_
#define _XXX_h0_
#include "JSC.h"
const DP default_req_prec = 1.0e-14;
const int default_max_rec = 10;
namespace JSC {
inline DP Integrand_11 (Vect_DP args)
{
// args[0] corresponds to t, args[1] to rho
return((exp(args[0]) * sinh(args[0]) * cos(4.0 * args[0] * args[1])/(2.0 * pow(cosh(args[0]), 2.0)) + 2.0 * pow(sin(2.0 * args[0] * args[1]), 2.0))/args[0]);
}
inline DP Integrand_12 (Vect_DP args)
{
DP expm2t = exp(-2.0*args[0]);
return(cos(4.0 * args[0] * args[1]) * expm2t * (3.0 + expm2t)/ (args[0] * (1.0 + expm2t) * (1.0 + expm2t)));
}
inline DP Integrand_2 (Vect_DP args)
{
DP answer = 0.0;
if (args[0] < 1.0) answer = exp(args[0]) * pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * sinh(args[0]) * pow(cosh(args[0]), 2.0));
else if (args[0] >= 1.0) {
DP expm2t = exp(-2.0 * args[0]);
answer = 8.0 * expm2t * pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * (1.0 - expm2t) * (1.0 + expm2t) * (1.0 + expm2t));
}
return(answer);
}
inline DP Integrand_A (Vect_DP args)
{
// This kernel is for -ln | A_-(i\pi/2) | function
return(exp(args[0]) * pow(sinh(args[0]/2.0), 2.0)/(args[0] * sinh(2.0*args[0]) * cosh(args[0])));
}
DP I_integral (DP rho, DP req_prec);
/********************* TWO SPINONS ********************/
DP SF_2p (DP k, DP omega, I_table Itable);
DP SF_2p (Vect_DP args, I_table Itable);
DP SF_2p_alt (Vect_DP args, I_table Itable);
DP SF_2p_w (Vect_DP args, I_table Itable);
DP SF_2p_w_alt (Vect_DP args, I_table Itable);
DP SF_2p_intw (Vect_DP args, I_table Itable);
DP SF_2p_intw_alt (Vect_DP args, I_table Itable);
DP SF_2p_check_sumrule (DP req_prec, int max_rec, I_table Itable);
DP SF_2p_check_sumrule_alt (DP req_prec, int max_rec, I_table Itable);
DP Fixed_k_sumrule_w (DP k);
DP Fixed_k_sumrule_omega (DP k);
DP SF_2p_check_fixed_k_sumrule (DP k, DP req_prec, int max_rec, I_table Itable);
DP SF_2p_check_fixed_k_sumrule_alt (DP k, DP req_prec, int max_rec, I_table Itable);
DP SF_2p_check_fixed_k_sumrule_opt (DP k, DP req_prec, int Npts, I_table Itable);
/********************** FOUR SPINONS **********************/
DP Sum_norm_gl (Vect_DP rho, DP req_prec);
DP Compute_C4 (DP req_prec);
DP SF_contrib (Vect_DP p, DP req_prec, I_table Itable);
DP J_fn (Vect_DP p, DP req_prec, I_table Itable);
inline DP Jacobian_p3p4_KW (DP k, DP w, DP K, DP W)
{
return(1.0/sqrt(pow(twoPI * sin(0.5 * (k - K)), 2.0) - (w-W)*(w-W)));
}
bool Set_p_given_kwKW (DP k, DP w, DP K, DP W, Vect_DP& p);
inline DP wmin_4p (DP k)
{
return(PI * fabs(sin(k)));
}
inline DP wmax_4p (DP k)
{
return(2.0 * PI * sqrt(2.0 * (1.0 + fabs(cos(0.5*k)))));
}
inline DP Wmin (DP k, DP w, DP K)
{
return(JSC::max(1.0e-15, JSC::max(fabs(PI * sin(K)), w - twoPI * sin(0.5 * (fabs(k-K))))));
}
inline DP Wmax (DP k, DP w, DP K)
{
return(JSC::min(twoPI * sin(0.5 * K), w - fabs(PI * sin(k - K))));
}
DP G_fn (Vect_DP args_to_G, I_table Itable);
DP G1_fn (Vect_DP args_to_G, I_table Itable);
DP G2_fn (Vect_DP args_to_G, I_table Itable);
DP G1_fn_mid (Vect_DP args_to_G, I_table Itable);
DP G2_fn_mid (Vect_DP args_to_G, I_table Itable);
DP G_fn_alt (Vect_DP args_to_G, I_table Itable);
DP H_fn (Vect_DP args_to_H, I_table Itable);
DP H2_fn (Vect_DP args_to_H, I_table Itable);
DP H_fn_mid (Vect_DP args_to_H, I_table Itable);
DP H_fn_alt (Vect_DP args_to_H, I_table Itable);
DP SF_4p_kwKW (Vect_DP args, I_table Itable);
DP SF_4p_kwKW_alpha (Vect_DP args, I_table Itable);
DP SF_4p_kwKW_alpha_opt (Vect_DP args, I_table Itable);
// Interface to used version:
DP SF_4p_rec (DP k, DP omega, DP req_prec, int max_rec, I_table Itable);
DP SF_4p (DP k, DP omega, I_table Itable);
DP SF_4p_opt (DP k, DP omega, DP req_prec, int Npts_K, int Npts_W, I_table Itable);
void Translate_raw_4p_data (DP k, int max_rec_w, const char* SFraw_Cstr, const char* SF_Cstr, const char* SFsrc_Cstr, I_table Itable);
DP SF_4p_rec (DP k, DP req_prec, int max_rec_w, int max_rec, I_table Itable);
Integral_result SF_4p_opt (DP k, DP req_prec, int Npts, I_table Itable);
Integral_result SF_4p_opt (DP k, DP req_prec, int Npts_w, int Npts_KW, I_table Itable);
Integral_result SF_4p_opt (DP k, DP req_prec, int Npts_w, int Npts_K, int Npts_W, I_table Itable);
//******************************** Functions to produce files similar to ABACUS **********************************
void Produce_SF_2p_file (int N, int Nomega, DP omegamax, I_table Itable);
void Produce_SF_4p_file (int N, int Nomega, DP omegamax, DP req_prec, int max_rec, I_table Itable);
void Produce_SF_4p_file (int N, int Nomega, DP omegamax, DP req_prec, int Npts_K, int Npts_W, I_table Itable);
//******************************** New version, full k and omega integral in one go ******************************
DP Direct_J_integral (int Npts_p, DP req_prec, I_table Itable);
DP Direct_J_integral_bin (int Npts_p, int Npts_o, DP req_prec, I_table Itable);
void Smoothen_raw_SF_4p (int Npts_p, int Npts_o, DP req_prec, DP width);
} // namespace JSC
#endif

86
include/JSC_XXZ_h0.h Archivo normal
Ver fichero

@ -0,0 +1,86 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_XXZ_h0.h
Purpose: Declares classes for XXZ in zero field: quantum group stuff.
***********************************************************/
#ifndef _XXZ_h0_
#define _XXZ_h0_
#include "JSC.h"
//const DP default_req_prec = 1.0e-14;
//const int default_max_rec = 10;
namespace JSC {
/*
inline DP Integrand_xi_11 (Vect_DP args)
{
// args[0] corresponds to t, args[1] to rho, args[2] to xi
//return((exp(args[0]) * sinh(args[0]) * cos(4.0 * args[0] * args[1])/(2.0 * pow(cosh(args[0]), 2.0)) + 2.0 * pow(sin(2.0 * args[0] * args[1]), 2.0))/args[0]);
return((sinh(args[0]*(1.0 + args[2])) * sinh(args[0]) * cos(4.0 * args[0] * args[1])/(2.0 * sinh(args[0] * args[2]) * pow(cosh(args[0]), 2.0))
+ 2.0 * pow(sin(2.0 * args[0] * args[1]), 2.0))/args[0]);
}
inline DP Integrand_xi_12 (Vect_DP args)
{
DP expm2t = exp(-2.0*args[0]);
DP expm2txi = exp(-2.0*args[0]*args[2]);
//return(cos(4.0 * args[0] * args[1]) * expm2t * (3.0 + expm2t)/ (args[0] * (1.0 + expm2t) * (1.0 + expm2t)));
return(cos(4.0 * args[0] * args[1]) * (expm2t * (3.0 * (1.0 + expm2txi) + expm2t) + expm2txi) / (args[0] * (1.0 - expm2txi) * (1.0 + expm2t) * (1.0 + expm2t)));
}
*/
/*
inline DP Integrand_xi_2 (Vect_DP args)
{
DP answer = 0.0;
if (args[0] < 1.0)
//answer = exp(args[0]) * pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * sinh(args[0]) * pow(cosh(args[0]), 2.0));
answer = sinh(args[0] * (args[2] + 1.0)) * pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * sinh(args[2] * args[0]) * sinh(args[0]) * pow(cosh(args[0]), 2.0));
else if (args[0] >= 1.0) {
DP expm2t = exp(-2.0 * args[0]);
DP expm2txi = exp(-2.0*args[0]*args[2]);
//answer = 8.0 * expm2t * pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * (1.0 - expm2t) * (1.0 + expm2t) * (1.0 + expm2t));
answer = 8.0 * ((1.0 - expm2t*expm2txi)/(1.0 - expm2t*expm2txi)) * expm2t *
pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * (1.0 - expm2t) * (1.0 + expm2t) * (1.0 + expm2t));
}
return(answer);
}
*/
DP I_xi_integral (DP xi, DP rho, DP req_prec, int max_nr_pts);
/********************* TWO SPINONS ********************/
DP Szz_XXZ_h0_2spinons (DP k, DP omega, Integral_table Itable);
DP Szz_XXZ_h0_2spinons (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_alt (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_omega (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_omega_alt (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_intomega (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_intomega_alt (Vect_DP args, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_check_sumrule (DP Delta, DP req_prec, int max_nr_pts, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_check_sumrule_alt (DP Delta, DP req_prec, int max_nr_pts, Integral_table Itable);
DP Fixed_k_sumrule_omega_Szz_XXZ_h0_N (DP Delta, DP k);
DP GSE_XXZ_h0 (DP Delta, DP req_prec, int max_nr_pts);
DP Fixed_k_sumrule_omega_Szz_XXZ_h0 (DP Delta, DP k, DP req_prec, int max_nr_pts);
DP Szz_XXZ_h0_2spinons_check_fixed_k_Szz_sumrule (DP Delta, DP k, DP req_prec, int max_nr_pts, Integral_table Itable);
DP Szz_XXZ_h0_2spinons_check_fixed_k_Szz_sumrule_alt (DP Delta, DP k, DP req_prec, int max_nr_pts, Integral_table Itable);
//******************************** Functions to produce files similar to ABACUS **********************************
void Produce_Szz_XXZ_h0_2spinons_file (DP Delta, int N, int Nomega, DP omegamax, Integral_table Itable);
void Produce_Szz_XXZ_h0_2spinons_fixed_K_file (DP Delta, DP Kover2PI, int Nomega, Integral_table Itable);
} // namespace JSC
#endif

118
include/JSC_Young.h Archivo normal
Ver fichero

@ -0,0 +1,118 @@
/**********************************************************
This software is part of J.-S. Caux's ABACUS library.
Copyright (c).
-----------------------------------------------------------
File: JSC_Young.h
Purpose: Declares Young tableau class.
***********************************************************/
#ifndef _YOUNG_
#define _YOUNG_
#include "JSC_Vect.h"
namespace JSC {
const int YOUNG_TABLEAU_ID_OPTION = 0;
const long long int TABLEAU_ID_UPPER_LIMIT = 10000000LL;
//***********************************************************************
class Young_Tableau {
public:
int Nrows;
int Ncols;
int* Row_L;
int* Col_L;
long long int id; // identification number
long long int maxid;
long long int* map;
bool map_computed;
long long int idnr_reached;
int nboxes_reached;
private:
int dimchoose;
long long int* choose_table;
public:
Young_Tableau (); // empty constructor, does nothing
Young_Tableau (int Nr, int Nc); // constructs empty tableau
Young_Tableau (int Nr, int Nc, long long int idnr); // constructs the tableau corresponding to identification number idnr
Young_Tableau (const Young_Tableau& RefTableau); // copy constructor
Young_Tableau (int Nr, int Nc, const Young_Tableau& RefTableau);
Young_Tableau& operator= (const Young_Tableau& RefTableau); // assignment
~Young_Tableau (); // destructor
public:
Young_Tableau& Compute_Map (long long int idnr_to_reach); // fills the map vector
Young_Tableau& Distribute_boxes (int nboxes_to_dist, int level);
Young_Tableau& Set_to_id (long long int idnr); // sets the tableau to the one corresponding to idnr
Young_Tableau& Set_to_id (long long int idnr, int option); // sets the tableau to the one corresponding to idnr according to rule option
Young_Tableau& Set_Row_L (Vect<int>& Row_Lengths); // set row lengths
Young_Tableau& Set_Col_L_given_Row_L (); // sets the Col_L array self-consistently
Young_Tableau& Set_Row_L_given_Col_L (); // sets the Col_L array self-consistently
long long int Compute_Descendent_id (int option, Vect<int>& Desc_Row_L, int Nrows_Desc, int Ncols_Desc,
const Young_Tableau& RefTableau);
Young_Tableau& Compute_id(); // computes the id number of tableau
Young_Tableau& Compute_id(int option); // computes the id number of tableau according to rule option
Young_Tableau& Print(); // couts the tableau
bool Lower_Row (int i);
bool Raise_Row (int i);
bool Lower_Col (int i);
bool Raise_Col (int i);
bool Raise_Lowest_Nonzero_Row(); // adds a box to the lowest nonzero length Row, recomputes id, returns true if tableau has changed
bool Raise_Next_to_Lowest_Nonzero_Row(); // same thing, but for Row under lowest nonzero length one.
bool Move_Box_from_Col_to_Col (int ifrom, int ito);
Vect<Young_Tableau> Descendents (int fixed_Nboxes);
Vect<Young_Tableau> Descendents_Boosted_State (int fixed_Nboxes);
int Add_Boxes_From_Lowest (int Nboxes); // tries to add Nboxes to Tableau, returns number of boxes added.
};
std::ostream& operator<< (std::ostream& s, const Young_Tableau& tableau);
inline int Nr_Nonzero_Rows (const Vect<Young_Tableau>& Tableau_ref)
{
// This function checks the number of rows containing at least one box
// in the whole vector of Young tableaux given as argument.
// The usefulness is to force descent of states in which only a few
// excitations have started dispersing.
int nr_nonzero_rows = 0;
for (int i = 0; i < Tableau_ref.size(); ++i)
for (int alpha = 0; alpha < Tableau_ref[i].Nrows; ++alpha)
if (Tableau_ref[i].Row_L[alpha] > 0) nr_nonzero_rows++;
return(nr_nonzero_rows);
}
//***********************************************************************
class Tableau_Map {
public:
Vect<long long int> map;
long long int idnr_reached;
int nboxes_reached;
public:
Tableau_Map (int Nrows, int Ncols);
void Distribute_id (int nboxes_to_dist, int level, Young_Tableau& RefTableau);
};
} // namespace JSC
#endif

485
include/JSC_util.h Archivo normal
Ver fichero

@ -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_

307
src/BETHE/Base.cc Archivo normal
Ver fichero

@ -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

29
src/BETHE/Bethe_State.cc Archivo normal
Ver fichero

@ -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

277
src/BETHE/Offsets.cc Archivo normal
Ver fichero

@ -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

89
src/COMBI/Combinatorics.cc Archivo normal
Ver fichero

@ -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

43
src/EXECS/2CBG_ThLim.cc Archivo ejecutable
Ver fichero

@ -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);
}

84
src/EXECS/Analyze_RAW_File.cc Archivo normal
Ver fichero

@ -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);
}

147
src/EXECS/Check_RAW_File.cc Archivo normal
Ver fichero

@ -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);
}

142
src/EXECS/Heis_DSF.cc Archivo normal
Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

120
src/EXECS/Heis_DSF_par.cc Archivo normal
Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

127
src/EXECS/Heis_DSF_par_Run.cc Archivo normal
Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

62
src/EXECS/LiebLin_DSF.cc Archivo normal
Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

119
src/EXECS/LiebLin_DSF_par.cc Archivo normal
Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

45
src/EXECS/LiebLin_TBA.cc Archivo ejecutable
Ver fichero

@ -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);
}

44
src/EXECS/LiebLin_TBA_fixed_nbar.cc Archivo ejecutable
Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

60
src/EXECS/ODSLF_DSF.cc Archivo normal
Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

99
src/EXECS/RAW_File_Stats.cc Archivo normal
Ver fichero

@ -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);
}

90
src/EXECS/Smoothen_Heis_DSF.cc Archivo normal
Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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);
}

Ver fichero

@ -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.");
}

112
src/EXECS/XXZ_gpd_StagSz_h0.cc Archivo normal
Ver fichero

@ -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);
}

41
src/FITTING/covsrt.cc Archivo normal
Ver fichero

@ -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--;
}
}
}
}

73
src/FITTING/lin_reg.cc Archivo normal
Ver fichero

@ -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;
}
}

127
src/FITTING/mrq.cc Archivo normal
Ver fichero

@ -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];
}
}

35
src/FITTING/polint.cc Archivo normal
Ver fichero

@ -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--]));
}
}

36
src/FITTING/polint_cx.cc Archivo normal
Ver fichero

@ -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--]));
}
}

1717
src/HEIS/Heis.cc Archivo normal

La diferencia del archivo ha sido suprimido porque es demasiado grande Cargar Diff

142
src/HEIS/Heis_Chem_Pot.cc Archivo normal
Ver fichero

@ -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
}
}

Ver fichero

@ -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

255
src/HEIS/Heis_Sumrules.cc Archivo normal
Ver fichero

@ -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

139
src/HEIS/M_vs_H.cc Archivo normal
Ver fichero

@ -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);
}
}

626
src/HEIS/XXX_Bethe_State.cc Archivo normal
Ver fichero

@ -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

646
src/HEIS/XXZ_Bethe_State.cc Archivo normal
Ver fichero

@ -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

814
src/HEIS/XXZ_gpd_Bethe_State.cc Archivo normal
Ver fichero

@ -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

253
src/HEIS/ln_Overlap_XXX.cc Archivo normal
Ver fichero

@ -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

239
src/HEIS/ln_Smin_ME_XXX.cc Archivo normal
Ver fichero

@ -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

328
src/HEIS/ln_Smin_ME_XXZ.cc Archivo normal
Ver fichero

@ -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

303
src/HEIS/ln_Smin_ME_XXZ_gpd.cc Archivo normal
Ver fichero

@ -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

307
src/HEIS/ln_Smm_ME_XXX.cc Archivo normal
Ver fichero

@ -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

247
src/HEIS/ln_Sz_ME_XXX.cc Archivo normal
Ver fichero

@ -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

563
src/HEIS/ln_Sz_ME_XXZ.cc Archivo normal
Ver fichero

@ -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

304
src/HEIS/ln_Sz_ME_XXZ_gpd.cc Archivo normal
Ver fichero

@ -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

502
src/HEIS/ln_Szm_p_Smz_ME_XXX.cc Archivo normal
Ver fichero

@ -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

Algunos archivos no se mostraron porque demasiados archivos han cambiado en esta diferencia Ver más