Browse Source

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

master
J.-S. Caux 6 years ago
parent
commit
103cbe84d6
100 changed files with 19886 additions and 0 deletions
  1. 9
    0
      .gitignore
  2. 492
    0
      Makefile
  3. 233
    0
      README.md
  4. 122
    0
      include/JSC.h
  5. 109
    0
      include/JSC_Bethe.h
  6. 51
    0
      include/JSC_Combi.h
  7. 37
    0
      include/JSC_Fitting.h
  8. 777
    0
      include/JSC_Heis.h
  9. 32
    0
      include/JSC_Infprec.h
  10. 331
    0
      include/JSC_Integ.h
  11. 190
    0
      include/JSC_LiebLin.h
  12. 440
    0
      include/JSC_Matrix.h
  13. 36
    0
      include/JSC_NRG.h
  14. 463
    0
      include/JSC_ODSLF.h
  15. 1263
    0
      include/JSC_Scan.h
  16. 207
    0
      include/JSC_Spec_Fns.h
  17. 47
    0
      include/JSC_State_Ensemble.h
  18. 147
    0
      include/JSC_TBA.h
  19. 472
    0
      include/JSC_Vect.h
  20. 139
    0
      include/JSC_XXX_h0.h
  21. 86
    0
      include/JSC_XXZ_h0.h
  22. 118
    0
      include/JSC_Young.h
  23. 485
    0
      include/JSC_util.h
  24. 307
    0
      src/BETHE/Base.cc
  25. 29
    0
      src/BETHE/Bethe_State.cc
  26. 277
    0
      src/BETHE/Offsets.cc
  27. 89
    0
      src/COMBI/Combinatorics.cc
  28. 43
    0
      src/EXECS/2CBG_ThLim.cc
  29. 84
    0
      src/EXECS/Analyze_RAW_File.cc
  30. 147
    0
      src/EXECS/Check_RAW_File.cc
  31. 142
    0
      src/EXECS/Heis_DSF.cc
  32. 133
    0
      src/EXECS/Heis_DSF_GeneralState.cc
  33. 120
    0
      src/EXECS/Heis_DSF_par.cc
  34. 75
    0
      src/EXECS/Heis_DSF_par_Prepare.cc
  35. 127
    0
      src/EXECS/Heis_DSF_par_Run.cc
  36. 75
    0
      src/EXECS/Heis_DSF_par_Wrapup.cc
  37. 116
    0
      src/EXECS/LiebLin_Catalogue_Fixed_c_k_Nscaling.cc
  38. 62
    0
      src/EXECS/LiebLin_DSF.cc
  39. 97
    0
      src/EXECS/LiebLin_DSF_GeneralState.cc
  40. 106
    0
      src/EXECS/LiebLin_DSF_GeneralState_par_Prepare.cc
  41. 153
    0
      src/EXECS/LiebLin_DSF_GeneralState_par_Run.cc
  42. 104
    0
      src/EXECS/LiebLin_DSF_GeneralState_par_Wrapup.cc
  43. 84
    0
      src/EXECS/LiebLin_DSF_MosesState.cc
  44. 139
    0
      src/EXECS/LiebLin_DSF_MosesState_par.cc
  45. 96
    0
      src/EXECS/LiebLin_DSF_MosesState_par_Prepare.cc
  46. 162
    0
      src/EXECS/LiebLin_DSF_MosesState_par_Run.cc
  47. 96
    0
      src/EXECS/LiebLin_DSF_MosesState_par_Wrapup.cc
  48. 99
    0
      src/EXECS/LiebLin_DSF_over_Ensemble.cc
  49. 191
    0
      src/EXECS/LiebLin_DSF_over_Ensemble_par.cc
  50. 119
    0
      src/EXECS/LiebLin_DSF_par.cc
  51. 77
    0
      src/EXECS/LiebLin_DSF_par_Prepare.cc
  52. 120
    0
      src/EXECS/LiebLin_DSF_par_Run.cc
  53. 77
    0
      src/EXECS/LiebLin_DSF_par_Wrapup.cc
  54. 92
    0
      src/EXECS/LiebLin_DSF_tester.cc
  55. 92
    0
      src/EXECS/LiebLin_DSF_tester_Ix2.cc
  56. 120
    0
      src/EXECS/LiebLin_Data_Daemon.cc
  57. 104
    0
      src/EXECS/LiebLin_Data_Daemon_Nscaling.cc
  58. 149
    0
      src/EXECS/LiebLin_Fourier_ssf_to_Qsqx.cc
  59. 132
    0
      src/EXECS/LiebLin_Fourier_to_t_equal_x.cc
  60. 118
    0
      src/EXECS/LiebLin_Fourier_to_t_equal_x_from_RAW.cc
  61. 191
    0
      src/EXECS/LiebLin_Fourier_to_x_equal_t.cc
  62. 147
    0
      src/EXECS/LiebLin_Fourier_to_x_equal_t_from_RAW.cc
  63. 79
    0
      src/EXECS/LiebLin_Moses_tester.cc
  64. 134
    0
      src/EXECS/LiebLin_RAW_File_Stats.cc
  65. 45
    0
      src/EXECS/LiebLin_TBA.cc
  66. 44
    0
      src/EXECS/LiebLin_TBA_fixed_nbar.cc
  67. 43
    0
      src/EXECS/LiebLin_TBA_fixed_nbar_ebar.cc
  68. 60
    0
      src/EXECS/ODSLF_DSF.cc
  69. 37
    0
      src/EXECS/Produce_Sorted_RAW_File.cc
  70. 99
    0
      src/EXECS/RAW_File_Stats.cc
  71. 90
    0
      src/EXECS/Smoothen_Heis_DSF.cc
  72. 111
    0
      src/EXECS/Smoothen_LiebLin_DSF.cc
  73. 120
    0
      src/EXECS/Smoothen_LiebLin_DSF_GeneralState.cc
  74. 97
    0
      src/EXECS/Smoothen_LiebLin_DSF_MosesState.cc
  75. 82
    0
      src/EXECS/Smoothen_LiebLin_DSF_Scaled.cc
  76. 103
    0
      src/EXECS/Smoothen_LiebLin_DSF_over_Ensemble.cc
  77. 82
    0
      src/EXECS/Smoothen_ODSLF_DSF.cc
  78. 112
    0
      src/EXECS/XXZ_gpd_StagSz_h0.cc
  79. 41
    0
      src/FITTING/covsrt.cc
  80. 73
    0
      src/FITTING/lin_reg.cc
  81. 127
    0
      src/FITTING/mrq.cc
  82. 35
    0
      src/FITTING/polint.cc
  83. 36
    0
      src/FITTING/polint_cx.cc
  84. 1717
    0
      src/HEIS/Heis.cc
  85. 142
    0
      src/HEIS/Heis_Chem_Pot.cc
  86. 376
    0
      src/HEIS/Heis_Matrix_Element_Contrib.cc
  87. 255
    0
      src/HEIS/Heis_Sumrules.cc
  88. 139
    0
      src/HEIS/M_vs_H.cc
  89. 626
    0
      src/HEIS/XXX_Bethe_State.cc
  90. 646
    0
      src/HEIS/XXZ_Bethe_State.cc
  91. 814
    0
      src/HEIS/XXZ_gpd_Bethe_State.cc
  92. 253
    0
      src/HEIS/ln_Overlap_XXX.cc
  93. 239
    0
      src/HEIS/ln_Smin_ME_XXX.cc
  94. 328
    0
      src/HEIS/ln_Smin_ME_XXZ.cc
  95. 303
    0
      src/HEIS/ln_Smin_ME_XXZ_gpd.cc
  96. 307
    0
      src/HEIS/ln_Smm_ME_XXX.cc
  97. 247
    0
      src/HEIS/ln_Sz_ME_XXX.cc
  98. 563
    0
      src/HEIS/ln_Sz_ME_XXZ.cc
  99. 304
    0
      src/HEIS/ln_Sz_ME_XXZ_gpd.cc
  100. 0
    0
      src/HEIS/ln_Szm_p_Smz_ME_XXX.cc

+ 9
- 0
.gitignore View File

@@ -0,0 +1,9 @@
1
+.DS_Store
2
+
3
+*~
4
+
5
+*tar.gz
6
+
7
+bin/*
8
+lib/*
9
+obj/*

+ 492
- 0
Makefile View File

@@ -0,0 +1,492 @@
1
+#**********************************************************
2
+#
3
+# This software is part of J.-S. Caux's ABACUS++ library.
4
+#
5
+# Copyright (c).
6
+#
7
+#-----------------------------------------------------------
8
+#
9
+# File:  Makefile
10
+#
11
+#
12
+#***********************************************************/
13
+
14
+VERSION = ABACUS++G_8
15
+
16
+# Base directory, tree of all source files, headers 
17
+BASEDIR = #/Users/jcaux/WORK/ABACUS++/
18
+OBJDIR = $(BASEDIR)obj/
19
+HEADDIR = $(BASEDIR)include/
20
+LIBDIR = $(BASEDIR)lib/
21
+SRCDIR = $(BASEDIR)src/
22
+EXECSDIR = $(BASEDIR)src/EXECS/
23
+BINDIR = $(BASEDIR)bin/
24
+
25
+#COMPILE = g++ -Wall -I$(BASEDIR)include/ -L$(LIBDIR) -O3 -stdlib=libstdc++
26
+#COMPILE = g++ -Wall -I$(BASEDIR)include/ -L$(LIBDIR) -O3 
27
+COMPILE = g++ -I$(BASEDIR)include/ -L$(LIBDIR) -O3 -w -fopenmp
28
+#COMPILE_MPI = mpicxx -I$(BASEDIR)include/ -L$(LIBDIR) -O3 -stdlib=libstdc++
29
+COMPILE_MPI = mpicxx -I$(BASEDIR)include/ -L$(LIBDIR) -O3 -w -fopenmp
30
+#COMPILE_OMP = g++ -I$(BASEDIR)include/ -L$(LIBDIR) -O3 -w -fopenmp
31
+
32
+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
33
+
34
+vpath %.h $(HEADDIR)
35
+
36
+#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 
37
+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
38
+#Headers_all = $(Headers_JSC) JSC_LiebLin.h JSC_Heis.h JSC_ODSLF.h JSC_Scan.h JSC_XXX_h0.h JSC_XXZ_h0.h
39
+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
40
+
41
+#Objects_BETHE = $(OBJDIR)Bethe_State.o
42
+
43
+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 \
44
+	$(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
45
+
46
+Objects_HEIS = $(OBJDIR)Heis.o $(OBJDIR)Heis_Chem_Pot.o $(OBJDIR)Heis_Sumrules.o $(OBJDIR)Heis_Matrix_Element_Contrib.o \
47
+	$(OBJDIR)ln_Overlap_XXX.o \
48
+	$(OBJDIR)ln_Sz_ME_XXX.o $(OBJDIR)ln_Sz_ME_XXZ.o $(OBJDIR)ln_Sz_ME_XXZ_gpd.o \
49
+	$(OBJDIR)ln_Smin_ME_XXX.o $(OBJDIR)ln_Smin_ME_XXZ.o $(OBJDIR)ln_Smin_ME_XXZ_gpd.o \
50
+	$(OBJDIR)ln_Szz_ME_XXX.o $(OBJDIR)ln_Smm_ME_XXX.o $(OBJDIR)ln_Szm_p_Smz_ME_XXX.o \
51
+	$(OBJDIR)M_vs_H.o \
52
+	$(OBJDIR)XXX_Bethe_State.o $(OBJDIR)XXZ_Bethe_State.o $(OBJDIR)XXZ_gpd_Bethe_State.o 
53
+
54
+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 \
55
+	$(OBJDIR)ln_Sz_ME_ODSLF_XXZ.o $(OBJDIR)ln_Smin_ME_ODSLF_XXZ.o
56
+
57
+Objects_COMBI = $(OBJDIR)Combinatorics.o
58
+
59
+Objects_FITTING = $(OBJDIR)covsrt.o $(OBJDIR)lin_reg.o $(OBJDIR)mrq.o $(OBJDIR)polint.o $(OBJDIR)polint_cx.o
60
+
61
+Objects_INTEG = $(OBJDIR)Integration.o
62
+
63
+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 \
64
+	$(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 \
65
+	$(OBJDIR)lubksb_CX.o $(OBJDIR)ludcmp.o $(OBJDIR)ludcmp_CX.o $(OBJDIR)pythag.o $(OBJDIR)tqli.o $(OBJDIR)tred2.o
66
+
67
+Objects_NRG = $(OBJDIR)NRG_State_Selector.o $(OBJDIR)NRG_DME_Matrix_Block_builder.o $(OBJDIR)NRG_K_Weight_integrand.o 
68
+
69
+#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
70
+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 
71
+
72
+Objects_TBA = $(OBJDIR)Root_Density.o $(OBJDIR)TBA_LiebLin.o $(OBJDIR)TBA_XXZ.o $(OBJDIR)TBA_2CBG.o
73
+
74
+#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
75
+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
76
+
77
+Objects_XXX_h0 = $(OBJDIR)XXX_h0.o
78
+
79
+Objects_XXZ_h0 = $(OBJDIR)XXZ_h0.o
80
+
81
+Objects_YOUNG = $(OBJDIR)Young_Tableau.o
82
+
83
+#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) 
84
+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) 
85
+
86
+#EXECS = $(BINDIR)LiebLin_DSF $(BINDIR)Smoothen_LiebLin_DSF $(BINDIR)Heis_DSF $(BINDIR)Smoothen_Heis_DSF $(BINDIR)Smoothen_Heis_ASF $(BINDIR)Check_RAW_File
87
+#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
88
+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
89
+
90
+
91
+##########################################
92
+# The library and the set of executables in bin/ are the ultimate targets
93
+
94
+lib$(VERSION).a : $(Objects_ALL)
95
+	ar -cru lib$(VERSION).a $(Objects_ALL)
96
+	mv lib$(VERSION).a $(BASEDIR)lib/
97
+	$(COMPILE) $(EXECSDIR)LiebLin_DSF.cc -o $(BINDIR)LiebLin_DSF -l$(VERSION)
98
+	$(COMPILE) $(EXECSDIR)LiebLin_Data_Daemon.cc -o $(BINDIR)LiebLin_Data_Daemon -l$(VERSION)
99
+	$(COMPILE) $(EXECSDIR)LiebLin_Data_Daemon_Nscaling.cc -o $(BINDIR)LiebLin_Data_Daemon_Nscaling -l$(VERSION)
100
+	$(COMPILE) $(EXECSDIR)LiebLin_Catalogue_Fixed_c_k_Nscaling.cc -o $(BINDIR)LiebLin_Catalogue_Fixed_c_k_Nscaling -l$(VERSION)
101
+	$(COMPILE) $(EXECSDIR)LiebLin_RAW_File_Stats.cc -o $(BINDIR)LiebLin_RAW_File_Stats -l$(VERSION)
102
+	$(COMPILE) $(EXECSDIR)LiebLin_DSF_GeneralState.cc -o $(BINDIR)LiebLin_DSF_GeneralState -l$(VERSION)
103
+#	$(COMPILE) $(EXECSDIR)LiebLin_DSF_MosesState.cc -o $(BINDIR)LiebLin_DSF_MosesState -l$(VERSION)
104
+	$(COMPILE) $(EXECSDIR)LiebLin_DSF_over_Ensemble.cc -o $(BINDIR)LiebLin_DSF_over_Ensemble -l$(VERSION)
105
+	$(COMPILE) $(EXECSDIR)LiebLin_DSF_tester.cc -o $(BINDIR)LiebLin_DSF_tester -l$(VERSION)
106
+	$(COMPILE) $(EXECSDIR)LiebLin_DSF_tester_Ix2.cc -o $(BINDIR)LiebLin_DSF_tester_Ix2 -l$(VERSION)
107
+#	$(COMPILE) $(EXECSDIR)LiebLin_Moses_tester.cc -o $(BINDIR)LiebLin_Moses_tester -l$(VERSION)
108
+	$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF.cc -o $(BINDIR)Smoothen_LiebLin_DSF -l$(VERSION)
109
+	$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF_Scaled.cc -o $(BINDIR)Smoothen_LiebLin_DSF_Scaled -l$(VERSION)
110
+	$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF_over_Ensemble.cc -o $(BINDIR)Smoothen_LiebLin_DSF_over_Ensemble -l$(VERSION)
111
+	$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF_GeneralState.cc -o $(BINDIR)Smoothen_LiebLin_DSF_GeneralState -l$(VERSION)
112
+#	$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF_MosesState.cc -o $(BINDIR)Smoothen_LiebLin_DSF_MosesState -l$(VERSION)
113
+	$(COMPILE) $(EXECSDIR)LiebLin_TBA.cc -o $(BINDIR)LiebLin_TBA -l$(VERSION)
114
+	$(COMPILE) $(EXECSDIR)LiebLin_TBA_fixed_nbar.cc -o $(BINDIR)LiebLin_TBA_fixed_nbar -l$(VERSION)
115
+	$(COMPILE) $(EXECSDIR)LiebLin_TBA_fixed_nbar_ebar.cc -o $(BINDIR)LiebLin_TBA_fixed_nbar_ebar -l$(VERSION)
116
+#	$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF_DiK.cc -o $(BINDIR)Smoothen_LiebLin_DSF_DiK -l$(VERSION)
117
+#	$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_ASF.cc -o $(BINDIR)Smoothen_LiebLin_ASF -l$(VERSION)
118
+	$(COMPILE) $(EXECSDIR)Heis_DSF.cc -o $(BINDIR)Heis_DSF -l$(VERSION)
119
+	$(COMPILE) $(EXECSDIR)Heis_DSF_GeneralState.cc -o $(BINDIR)Heis_DSF_GeneralState -l$(VERSION)
120
+	$(COMPILE) $(EXECSDIR)Smoothen_Heis_DSF.cc -o $(BINDIR)Smoothen_Heis_DSF -l$(VERSION)
121
+#	$(COMPILE) $(EXECSDIR)Smoothen_Heis_ASF.cc -o $(BINDIR)Smoothen_Heis_ASF -l$(VERSION)
122
+	$(COMPILE) $(EXECSDIR)XXZ_gpd_StagSz_h0.cc -o $(BINDIR)XXZ_gpd_StagSz_h0 -l$(VERSION)
123
+#	$(COMPILE) $(EXECSDIR)ODSLF_DSF.cc -o $(BINDIR)ODSLF_DSF -l$(VERSION)
124
+#	$(COMPILE) $(EXECSDIR)Smoothen_ODSLF_DSF.cc -o $(BINDIR)Smoothen_ODSLF_DSF -l$(VERSION)
125
+	$(COMPILE) $(EXECSDIR)Check_RAW_File.cc -o $(BINDIR)Check_RAW_File -l$(VERSION)
126
+	$(COMPILE) $(EXECSDIR)Analyze_RAW_File.cc -o $(BINDIR)Analyze_RAW_File -l$(VERSION)
127
+	$(COMPILE) $(EXECSDIR)RAW_File_Stats.cc -o $(BINDIR)RAW_File_Stats -l$(VERSION)
128
+	$(COMPILE) $(EXECSDIR)Produce_Sorted_RAW_File.cc -o $(BINDIR)Produce_Sorted_RAW_File -l$(VERSION)
129
+	$(COMPILE) $(EXECSDIR)2CBG_ThLim.cc -o $(BINDIR)2CBG_ThLim -l$(VERSION)
130
+	$(COMPILE) $(EXECSDIR)LiebLin_Fourier_to_x_equal_t.cc -o $(BINDIR)LiebLin_Fourier_to_x_equal_t -l$(VERSION)	
131
+	$(COMPILE) $(EXECSDIR)LiebLin_Fourier_to_t_equal_x.cc -o $(BINDIR)LiebLin_Fourier_to_t_equal_x -l$(VERSION)	
132
+	$(COMPILE) $(EXECSDIR)LiebLin_Fourier_to_x_equal_t_from_RAW.cc -o $(BINDIR)LiebLin_Fourier_to_x_equal_t_from_RAW -l$(VERSION)	
133
+	$(COMPILE) $(EXECSDIR)LiebLin_Fourier_to_t_equal_x_from_RAW.cc -o $(BINDIR)LiebLin_Fourier_to_t_equal_x_from_RAW -l$(VERSION)	
134
+	$(COMPILE) $(EXECSDIR)LiebLin_Fourier_ssf_to_Qsqx.cc -o $(BINDIR)LiebLin_Fourier_ssf_to_Qsqx -l$(VERSION)	
135
+
136
+###########################################
137
+# Interacting LiebLin gas
138
+
139
+$(OBJDIR)LiebLin_Bethe_State.o : LiebLin_Bethe_State.cc $(Headers_JSC) JSC_LiebLin.h
140
+	$(COMPILE) -c $< -o $@
141
+
142
+$(OBJDIR)LiebLin_Chem_Pot.o : LiebLin_Chem_Pot.cc $(Headers_JSC) JSC_LiebLin.h
143
+	$(COMPILE) -c $< -o $@	
144
+
145
+$(OBJDIR)LiebLin_Matrix_Element_Contrib.o : LiebLin_Matrix_Element_Contrib.cc $(Headers_JSC) JSC_LiebLin.h
146
+	$(COMPILE) -c $< -o $@	
147
+
148
+$(OBJDIR)LiebLin_ln_Overlap.o : LiebLin_ln_Overlap.cc $(Headers_JSC) JSC_LiebLin.h
149
+	$(COMPILE) -c $< -o $@
150
+
151
+$(OBJDIR)LiebLin_Sumrules.o : LiebLin_Sumrules.cc $(Headers_JSC) JSC_LiebLin.h
152
+	$(COMPILE) -c $< -o $@
153
+
154
+$(OBJDIR)LiebLin_State_Ensemble.o : LiebLin_State_Ensemble.cc $(Headers_JSC) JSC_LiebLin.h
155
+	$(COMPILE) -c $< -o $@
156
+
157
+$(OBJDIR)LiebLin_Tgt0.o : LiebLin_Tgt0.cc $(Headers_JSC) JSC_LiebLin.h
158
+	$(COMPILE) -c $< -o $@
159
+
160
+$(OBJDIR)LiebLin_Twisted_lnnorm.o : LiebLin_Twisted_lnnorm.cc $(Headers_JSC) JSC_LiebLin.h
161
+	$(COMPILE) -c $< -o $@
162
+
163
+$(OBJDIR)LiebLin_Utils.o : LiebLin_Utils.cc $(Headers_JSC) JSC_LiebLin.h
164
+	$(COMPILE) -c $< -o $@	
165
+
166
+$(OBJDIR)ln_Density_ME.o : ln_Density_ME.cc $(Headers_JSC) JSC_LiebLin.h
167
+	$(COMPILE) -c $< -o $@
168
+
169
+$(OBJDIR)LiebLin_Twisted_ln_Overlap.o : LiebLin_Twisted_ln_Overlap.cc $(Headers_JSC) JSC_LiebLin.h
170
+	$(COMPILE) -c $< -o $@
171
+
172
+$(OBJDIR)ln_Psi_ME.o : ln_Psi_ME.cc $(Headers_JSC) JSC_LiebLin.h
173
+	$(COMPILE) -c $< -o $@
174
+
175
+$(OBJDIR)ln_g2_ME.o : ln_g2_ME.cc $(Headers_JSC) JSC_LiebLin.h
176
+	$(COMPILE) -c $< -o $@
177
+
178
+
179
+###########################################
180
+# Heisenberg chains
181
+
182
+$(OBJDIR)Heis.o : Heis.cc $(Headers_JSC) JSC_Heis.h
183
+	$(COMPILE) -c $< -o $@
184
+
185
+$(OBJDIR)Heis_Chem_Pot.o : Heis_Chem_Pot.cc $(Headers_JSC) JSC_Heis.h
186
+	$(COMPILE) -c $< -o $@
187
+
188
+$(OBJDIR)Heis_Sumrules.o : Heis_Sumrules.cc $(Headers_JSC) JSC_Heis.h
189
+	$(COMPILE) -c $< -o $@
190
+
191
+$(OBJDIR)Heis_Matrix_Element_Contrib.o : Heis_Matrix_Element_Contrib.cc $(Headers_JSC) JSC_Heis.h
192
+	$(COMPILE) -c $< -o $@
193
+
194
+$(OBJDIR)ln_Overlap_XXX.o : ln_Overlap_XXX.cc $(Headers_JSC) JSC_Heis.h 
195
+	$(COMPILE) -c $< -o $@
196
+
197
+$(OBJDIR)ln_Sz_ME_XXX.o : ln_Sz_ME_XXX.cc $(Headers_JSC) JSC_Heis.h 
198
+	$(COMPILE) -c $< -o $@
199
+
200
+$(OBJDIR)ln_Szz_ME_XXX.o : ln_Szz_ME_XXX.cc $(Headers_JSC) JSC_Heis.h 
201
+	$(COMPILE) -c $< -o $@
202
+
203
+$(OBJDIR)ln_Smm_ME_XXX.o : ln_Smm_ME_XXX.cc $(Headers_JSC) JSC_Heis.h 
204
+	$(COMPILE) -c $< -o $@
205
+
206
+$(OBJDIR)ln_Szm_p_Smz_ME_XXX.o : ln_Szm_p_Smz_ME_XXX.cc $(Headers_JSC) JSC_Heis.h 
207
+	$(COMPILE) -c $< -o $@
208
+
209
+$(OBJDIR)ln_Sz_ME_XXZ.o : ln_Sz_ME_XXZ.cc $(Headers_JSC) JSC_Heis.h 
210
+	$(COMPILE) -c $< -o $@
211
+
212
+$(OBJDIR)ln_Sz_ME_XXZ_gpd.o : ln_Sz_ME_XXZ_gpd.cc $(Headers_JSC) JSC_Heis.h 
213
+	$(COMPILE) -c $< -o $@
214
+
215
+$(OBJDIR)ln_Smin_ME_XXX.o : ln_Smin_ME_XXX.cc $(Headers_JSC) JSC_Heis.h 
216
+	$(COMPILE) -c $< -o $@
217
+
218
+$(OBJDIR)ln_Smin_ME_XXZ.o : ln_Smin_ME_XXZ.cc $(Headers_JSC) JSC_Heis.h 
219
+	$(COMPILE) -c $< -o $@
220
+
221
+$(OBJDIR)ln_Smin_ME_XXZ_gpd.o : ln_Smin_ME_XXZ_gpd.cc $(Headers_JSC) JSC_Heis.h
222
+	$(COMPILE) -c $< -o $@
223
+
224
+$(OBJDIR)M_vs_H.o : M_vs_H.cc $(Headers_JSC) JSC_Heis.h 
225
+	$(COMPILE) -c $< -o $@
226
+
227
+$(OBJDIR)XXX_Bethe_State.o : XXX_Bethe_State.cc $(Headers_JSC) JSC_Heis.h 
228
+	$(COMPILE) -c $< -o $@
229
+
230
+$(OBJDIR)XXZ_Bethe_State.o : XXZ_Bethe_State.cc $(Headers_JSC) JSC_Heis.h 
231
+	$(COMPILE) -c $< -o $@
232
+
233
+$(OBJDIR)XXZ_gpd_Bethe_State.o : XXZ_gpd_Bethe_State.cc $(Headers_JSC) JSC_Heis.h 
234
+	$(COMPILE) -c $< -o $@
235
+
236
+
237
+###########################################
238
+# One-d spinless fermions
239
+
240
+$(OBJDIR)ODSLF.o : ODSLF.cc $(Headers_JSC) JSC_Heis.h JSC_ODSLF.h
241
+	$(COMPILE) -c $< -o $@
242
+
243
+$(OBJDIR)ODSLF_Chem_Pot.o : ODSLF_Chem_Pot.cc $(Headers_JSC) JSC_ODSLF.h
244
+	$(COMPILE) -c $< -o $@
245
+
246
+$(OBJDIR)ODSLF_Sumrules.o : ODSLF_Sumrules.cc $(Headers_JSC) JSC_ODSLF.h
247
+	$(COMPILE) -c $< -o $@
248
+
249
+$(OBJDIR)ODSLF_XXZ_Bethe_State.o : ODSLF_XXZ_Bethe_State.cc $(Headers_JSC) JSC_Heis.h JSC_ODSLF.h
250
+	$(COMPILE) -c $< -o $@
251
+
252
+$(OBJDIR)ln_Smin_ME_ODSLF_XXZ.o : ln_Smin_ME_ODSLF_XXZ.cc $(Headers_JSC) JSC_ODSLF.h 
253
+	$(COMPILE) -c $< -o $@
254
+
255
+$(OBJDIR)ln_Sz_ME_ODSLF_XXZ.o : ln_Sz_ME_ODSLF_XXZ.cc $(Headers_JSC) JSC_ODSLF.h 
256
+	$(COMPILE) -c $< -o $@
257
+
258
+$(OBJDIR)ODSLF_Matrix_Element_Contrib.o : ODSLF_Matrix_Element_Contrib.cc $(Headers_JSC) JSC_ODSLF.h
259
+	$(COMPILE) -c $< -o $@
260
+
261
+
262
+###########################################
263
+# Combinatorics functions
264
+
265
+$(OBJDIR)Combinatorics.o : Combinatorics.cc $(Headers_JSC)
266
+	$(COMPILE) -c $< -o $@
267
+
268
+###########################################
269
+# Integ functions
270
+
271
+$(OBJDIR)Integration.o : Integration.cc $(Headers_JSC)
272
+	$(COMPILE) -c $< -o $@	
273
+
274
+###########################################
275
+# Fitting functions
276
+
277
+$(OBJDIR)covsrt.o : covsrt.cc $(Headers_JSC)
278
+	$(COMPILE) -c $< -o $@
279
+
280
+$(OBJDIR)lin_reg.o : lin_reg.cc $(Headers_JSC)
281
+	$(COMPILE) -c $< -o $@
282
+
283
+$(OBJDIR)mrq.o : mrq.cc $(Headers_JSC)
284
+	$(COMPILE) -c $< -o $@
285
+
286
+$(OBJDIR)polint.o : polint.cc $(Headers_JSC) 
287
+	$(COMPILE) -c $< -o $@
288
+
289
+$(OBJDIR)polint_cx.o : polint_cx.cc $(Headers_JSC) 
290
+	$(COMPILE) -c $< -o $@
291
+
292
+
293
+###########################################
294
+# Matrix functions
295
+
296
+$(OBJDIR)balanc.o : balanc.cc $(Headers_JSC) 
297
+	$(COMPILE) -c $< -o $@
298
+
299
+$(OBJDIR)det_LU.o : det_LU.cc $(Headers_JSC) 
300
+	$(COMPILE) -c $< -o $@
301
+
302
+$(OBJDIR)det_LU_CX.o : det_LU_CX.cc $(Headers_JSC)
303
+	$(COMPILE) -c $< -o $@
304
+
305
+$(OBJDIR)eigsrt.o : eigsrt.cc $(Headers_JSC) 
306
+	$(COMPILE) -c $< -o $@
307
+
308
+$(OBJDIR)elmhes.o : elmhes.cc $(Headers_JSC) 
309
+	$(COMPILE) -c $< -o $@
310
+
311
+$(OBJDIR)gaussj.o : gaussj.cc $(Headers_JSC) 
312
+	$(COMPILE) -c $< -o $@
313
+
314
+$(OBJDIR)hqr.o : hqr.cc $(Headers_JSC) 
315
+	$(COMPILE) -c $< -o $@
316
+
317
+$(OBJDIR)jacobi.o : jacobi.cc $(Headers_JSC) 
318
+	$(COMPILE) -c $< -o $@
319
+
320
+$(OBJDIR)lndet_LU.o : lndet_LU.cc $(Headers_JSC) 
321
+	$(COMPILE) -c $< -o $@
322
+
323
+$(OBJDIR)lndet_LU_CX.o : lndet_LU_CX.cc $(Headers_JSC) 
324
+	$(COMPILE) -c $< -o $@
325
+
326
+$(OBJDIR)lndet_LU_dstry.o : lndet_LU_dstry.cc $(Headers_JSC) 
327
+	$(COMPILE) -c $< -o $@
328
+
329
+$(OBJDIR)lndet_LU_CX_dstry.o : lndet_LU_CX_dstry.cc $(Headers_JSC) 
330
+	$(COMPILE) -c $< -o $@
331
+
332
+$(OBJDIR)lubksb.o : lubksb.cc $(Headers_JSC)
333
+	$(COMPILE) -c $< -o $@
334
+
335
+$(OBJDIR)lubksb_CX.o : lubksb_CX.cc $(Headers_JSC)
336
+	$(COMPILE) -c $< -o $@
337
+
338
+$(OBJDIR)ludcmp.o : ludcmp.cc $(Headers_JSC) 
339
+	$(COMPILE) -c $< -o $@
340
+
341
+$(OBJDIR)ludcmp_CX.o : ludcmp_CX.cc $(Headers_JSC) 
342
+	$(COMPILE) -c $< -o $@
343
+
344
+$(OBJDIR)pythag.o : pythag.cc $(Headers_JSC) 
345
+	$(COMPILE) -c $< -o $@
346
+
347
+$(OBJDIR)tqli.o : tqli.cc $(Headers_JSC) 
348
+	$(COMPILE) -c $< -o $@
349
+
350
+$(OBJDIR)tred2.o : tred2.cc $(Headers_JSC)
351
+	$(COMPILE) -c $< -o $@
352
+
353
+
354
+###########################################
355
+# NRG
356
+
357
+$(OBJDIR)NRG_K_Weight_integrand.o : NRG_K_Weight_integrand.cc $(Headers_all)
358
+	$(COMPILE) -c $< -o $@
359
+
360
+$(OBJDIR)NRG_State_Selector.o : NRG_State_Selector.cc $(Headers_all)
361
+	$(COMPILE) -c $< -o $@
362
+
363
+$(OBJDIR)NRG_DME_Matrix_Block_builder.o : NRG_DME_Matrix_Block_builder.cc $(Headers_all)
364
+	$(COMPILE) -c $< -o $@
365
+
366
+
367
+###########################################
368
+# Scan
369
+
370
+#$(OBJDIR)Base.o : Base.cc $(Headers_all)
371
+#	$(COMPILE) -c $< -o $@
372
+
373
+$(OBJDIR)Descendents.o : Descendents.cc $(Headers_all)
374
+	$(COMPILE) -c $< -o $@
375
+
376
+$(OBJDIR)General_Scan.o : General_Scan.cc $(Headers_all)
377
+	$(COMPILE) -c $< -o $@
378
+
379
+$(OBJDIR)General_Scan_Parallel.o : General_Scan_Parallel.cc $(Headers_all)
380
+	$(COMPILE) -c $< -o $@
381
+
382
+$(OBJDIR)Particle_Hole_Excitation_Cost.o : Particle_Hole_Excitation_Cost.cc $(Headers_all)
383
+	$(COMPILE) -c $< -o $@
384
+
385
+#$(OBJDIR)Offsets.o : Offsets.cc $(Headers_all)
386
+#	$(COMPILE) -c $< -o $@
387
+
388
+$(OBJDIR)Scan_Info.o : Scan_Info.cc $(Headers_all)
389
+	$(COMPILE) -c $< -o $@
390
+
391
+#$(OBJDIR)Scan_State_List.o : Scan_State_List.cc $(Headers_all)
392
+#	$(COMPILE) -c $< -o $@
393
+
394
+#$(OBJDIR)Scan_Thread_List.o : Scan_Thread_List.cc $(Headers_all)
395
+#$(OBJDIR)Scan_Thread_Set.o : Scan_Thread_Set.cc $(Headers_all)
396
+$(OBJDIR)Scan_Thread_Data.o : Scan_Thread_Data.cc $(Headers_all)
397
+	$(COMPILE) -c $< -o $@
398
+
399
+###########################################
400
+# Thermodynamic Bethe Ansatz
401
+
402
+$(OBJDIR)Root_Density.o : Root_Density.cc $(Headers_JSC) JSC_TBA.h
403
+	$(COMPILE) -c $< -o $@
404
+
405
+$(OBJDIR)TBA_LiebLin.o : TBA_LiebLin.cc $(Headers_JSC) JSC_TBA.h
406
+	$(COMPILE) -c $< -o $@
407
+
408
+$(OBJDIR)TBA_XXZ.o : TBA_XXZ.cc $(Headers_JSC) JSC_TBA.h
409
+	$(COMPILE) -c $< -o $@
410
+
411
+$(OBJDIR)TBA_2CBG.o : TBA_2CBG.cc $(Headers_JSC) JSC_TBA.h
412
+	$(COMPILE) -c $< -o $@
413
+
414
+###########################################
415
+# Utilities
416
+
417
+$(OBJDIR)Data_File_Name.o : Data_File_Name.cc $(Headers_all)
418
+	$(COMPILE) -c $< -o $@
419
+
420
+$(OBJDIR)K_and_Omega_Files.o : K_and_Omega_Files.cc $(Headers_all)
421
+	$(COMPILE) -c $< -o $@
422
+
423
+$(OBJDIR)Smoothen_RAW_into_SF.o : Smoothen_RAW_into_SF.cc $(Headers_all)
424
+	$(COMPILE) -c $< -o $@
425
+
426
+$(OBJDIR)Smoothen_RAW_into_SF_LiebLin_Scaled.o : Smoothen_RAW_into_SF_LiebLin_Scaled.cc $(Headers_all)
427
+	$(COMPILE) -c $< -o $@
428
+
429
+$(OBJDIR)Sort_RAW_File.o : Sort_RAW_File.cc $(Headers_all)
430
+	$(COMPILE) -c $< -o $@
431
+
432
+$(OBJDIR)State_Label.o : State_Label.cc $(Headers_all)
433
+	$(COMPILE) -c $< -o $@
434
+
435
+###########################################
436
+# XXX_h0
437
+
438
+$(OBJDIR)XXX_h0.o : XXX_h0.cc $(Headers_all) JSC_XXX_h0.h
439
+	$(COMPILE) -c $< -o $@
440
+
441
+###########################################
442
+# XXZ_h0
443
+
444
+$(OBJDIR)XXZ_h0.o : XXZ_h0.cc $(Headers_all) JSC_XXZ_h0.h
445
+	$(COMPILE) -c $< -o $@
446
+
447
+###########################################
448
+# Young Tableaux
449
+
450
+$(OBJDIR)Young_Tableau.o : Young_Tableau.cc $(Headers_all)
451
+	$(COMPILE) -c $< -o $@
452
+
453
+
454
+############################################
455
+
456
+#executables : 
457
+#	$(COMPILE) $(EXECSDIR)LiebLin_DSF.cc -o $(BINDIR)LiebLin_DSF -l$(VERSION)
458
+#	$(COMPILE) $(EXECSDIR)Smoothen_LiebLin_DSF.cc -o $(BINDIR)Smoothen_LiebLin_DSF -l$(VERSION)
459
+#	$(COMPILE) $(EXECSDIR)Heis_DSF.cc -o $(BINDIR)Heis_DSF -l$(VERSION)
460
+#	$(COMPILE) $(EXECSDIR)Smoothen_Heis_DSF.cc -o $(BINDIR)Smoothen_Heis_DSF -l$(VERSION)
461
+
462
+###########################################
463
+# Executables (parallel versions)
464
+
465
+parallel : 
466
+#	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_par.cc -o $(BINDIR)LiebLin_DSF_par -l$(VERSION)
467
+	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_par_Prepare.cc -o $(BINDIR)LiebLin_DSF_par_Prepare -l$(VERSION)
468
+	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_par_Run.cc -o $(BINDIR)LiebLin_DSF_par_Run -l$(VERSION)
469
+	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_par_Wrapup.cc -o $(BINDIR)LiebLin_DSF_par_Wrapup -l$(VERSION)
470
+	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_GeneralState_par_Prepare.cc -o $(BINDIR)LiebLin_DSF_GeneralState_par_Prepare -l$(VERSION)
471
+	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_GeneralState_par_Run.cc -o $(BINDIR)LiebLin_DSF_GeneralState_par_Run -l$(VERSION)
472
+	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_GeneralState_par_Wrapup.cc -o $(BINDIR)LiebLin_DSF_GeneralState_par_Wrapup -l$(VERSION)
473
+#	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_MosesState_par.cc -o $(BINDIR)LiebLin_DSF_MosesState_par -l$(VERSION)
474
+#	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_MosesState_par_Prepare.cc -o $(BINDIR)LiebLin_DSF_MosesState_par_Prepare -l$(VERSION)
475
+#	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_MosesState_par_Run.cc -o $(BINDIR)LiebLin_DSF_MosesState_par_Run -l$(VERSION)
476
+#	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_MosesState_par_Wrapup.cc -o $(BINDIR)LiebLin_DSF_MosesState_par_Wrapup -l$(VERSION)
477
+#	$(COMPILE_MPI) $(EXECSDIR)LiebLin_DSF_over_Ensemble_par.cc -o $(BINDIR)LiebLin_DSF_over_Ensemble_par -l$(VERSION)
478
+#	$(COMPILE_MPI) $(EXECSDIR)Heis_DSF_par.cc -o $(BINDIR)Heis_DSF_par -l$(VERSION)
479
+	$(COMPILE_MPI) $(EXECSDIR)Heis_DSF_par_Prepare.cc -o $(BINDIR)Heis_DSF_par_Prepare -l$(VERSION)
480
+	$(COMPILE_MPI) $(EXECSDIR)Heis_DSF_par_Run.cc -o $(BINDIR)Heis_DSF_par_Run -l$(VERSION)
481
+	$(COMPILE_MPI) $(EXECSDIR)Heis_DSF_par_Wrapup.cc -o $(BINDIR)Heis_DSF_par_Wrapup -l$(VERSION)
482
+
483
+
484
+###########################################
485
+# Cleanup
486
+
487
+clean :
488
+	/bin/rm -f $(Objects_ALL)
489
+	/bin/rm -f $(LIBDIR)$(VERSION)
490
+	/bin/rm -f $(EXECS)
491
+
492
+

+ 233
- 0
README.md View File

@@ -1,2 +1,235 @@
1 1
 # ABACUS
2 2
 
3
+Copyright (c) J.-S. Caux
4
+
5
+
6
+
7
+---
8
+
9
+Previous versions
10
+=================
11
+
12
+------------------------------------------------------------------
13
+## ABACUS++G_8 [started 2015 02 20] [published 2015 04 04]
14
+
15
+Building up on ++G_7.
16
+
17
+Objectives:
18
+
19
+- facilitate use of OpenMP, by removing the recursive aspect of descending. DONE.
20
+
21
+- improve memory use. DONE.
22
+  Replace in-memory Scan_Thread_Set by on-disk Scan_Thread_Data.
23
+  Uses Scan_Thread structure.
24
+
25
+Features:
26
+- OpenMP is implemented.
27
+- Scanning on spin chains is now implemented.
28
+- Scan_Info's Nfull now contains the sub-Hilbert space dimension (for spin chains; type == double)
29
+- Added the .stat file in General_Scan, containing info about expected data value and actually obtained one
30
+- Timing is more strictly enforced, using OpenMP wtime().
31
+
32
+Notes:
33
+- a first implementation using OpenMP is archived as ABACUS++G_8_v1.tar.gz package.
34
+
35
+------------------------------------------------------------------
36
+ABACUS++G_7 [published 2015 01 17]
37
+
38
+Building up on ++G_6.
39
+- Now using 15 types of descendents, enabling fixed iK scanning with increasing ph nrs.
40
+- Scan_Thread_List replaced by Scan_Thread_Set (to optimize performance and threads storage)
41
+
42
+Works well for LiebLin, including at finite T.
43
+
44
+TODO:
45
+- implement scanning for spin chains (scanning over bases still missing for generic AveragingState)
46
+
47
+------------------------------------------------------------------
48
+ABACUS++G_6 [started 2015 01]
49
+
50
+Simple scanning: iK stepped up, iK stepped down (from ++G_5).
51
+Fixed momentum scanning is thus implemented.
52
+
53
+Version 6.0: [published 2015 01 16]
54
+- uses 8 types of descendents
55
+- Works well for LiebLin, including finite T.
56
+
57
+Version 6.1: proto version of ++G_7
58
+- uses greater nr of descendents, 15, enforcing strict ph nr increase
59
+
60
+------------------------------------------------------------------
61
+ABACUS++G_5 [started 2014 12 11] [abandoned 2015 01, except for version 5.0 (great for GS of LiebLin)]
62
+
63
+Fundamental rewriting of scanning protocol.
64
+
65
+Version 5.0 works very well for ground state correlations of Lieb-Liniger.
66
+Heis: still bugged.
67
+
68
+------------------------------------------------------------------
69
+ABACUS++G_4 [started 2014 12 08] [abandoned 2014 12 11]
70
+
71
+Nontrivial bug: descending with inner and outer skeletons does not always
72
+preserve number of p-h excitations. Fatal for large c in LiebLin.
73
+
74
+- Descending with type 2: instead of summing over all new p and h positions,
75
+  just put p and h as close to each other as possible.
76
+  To implement this, added a new type of desc (4), where this distance is increased.
77
+
78
+TODO:
79
+- For XXX: inclusion of infinite rapidities as genuine particle type
80
+
81
+
82
+------------------------------------------------------------------
83
+ABACUS++G_3 [started 2014 11 10] [closed 2014 12 08]
84
+
85
+- Change of naming convention: LiebLin instead of Bose or 1DBG.
86
+- For LiebLin: changed rapidity naming convention: now lambdaoc, to make rescaling \lambda/c explicit
87
+- Improved small c algorithm for LiebLin
88
+- Fixed momentum scanning implemented using inner and outer skeleton logic
89
+
90
+------------------------------------------------------------------
91
+ABACUS++G_2 [closed 2014 11 10]
92
+[2013 09 20]
93
+- Scanning is now automatically over remaining pair of excitations; facilitates fixed iK scans
94
+- Threads are now over states with NScan-2 particles, intermediate states then include all Nscan states fulfilling the momentum constraints
95
+- Scanning for spin chains implemented (general states; also parallel). Needs further testing. Seems to work for ground state.
96
+
97
+------------------------------------------------------------------
98
+ABACUS++G_1.1
99
+
100
+[2013 09 06]
101
+Changed parallel version for Bose:
102
+- supercycle time is now an argument to functions
103
+- split the 'Prepare', 'Run' and 'Wrapup' into separate executables
104
+- added the 'filenamesuffix' argument to parallel functions
105
+
106
+
107
+------------------------------------------------------------------
108
+ABACUS++G_1
109
+
110
+New labelling and descending implemented for arbitrary states with strings, e.g. spin chains.
111
+
112
+Descendents for an arbitrary state are now generated according to the following logic.
113
+
114
+TO DO:
115
+Include string deviation value in Bethe_State objects and in RAW files. Form factors are always computed.
116
+
117
+
118
+[2013 08 25]
119
+Changed sum rules for LiebLin density-density: now using f-sumrule from iKmin to iKmax.
120
+
121
+
122
+Earlier notes for ABACUS++T:
123
+##############################################################
124
+
125
+Notable changes from ABACUS++:
126
+
127
+- 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.
128
+
129
+- 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.
130
+
131
+- 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.
132
+
133
+
134
+##############################################################
135
+
136
+IMPROVEMENTS YET TO BE IMPLEMENTED:
137
+
138
+- Some form of binning to make very large runs possible.
139
+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.
140
+Difficulties: the size of the .raw file is of the order of the .thr one, which must be kept.
141
+
142
+##############################################################
143
+
144
+VERSIONS: NOTES
145
+
146
+Important conventions:
147
+
148
+- Versions are numbered with two integers, [VERSION].[SUBVERSION]
149
+- 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.
150
+- Changes in version number indicate a larger scale revision affecting the conventions. Data produced with earlier versions are then deprecated.
151
+
152
+---------------------------------------------------------------
153
+
154
+ABACUS++T_1.0 [published 23 June 2011]
155
+
156
+First version of new setup and logic for ABACUS. Implementation of all basic new ideas for state labelling and descending.
157
+
158
+
159
+------------------------------------------------------------------
160
+
161
+ABACUS++T_2.0 [in progress][*ABANDONED*]
162
+
163
+Attempt at implementing fixed-momentum-based scanning.
164
+
165
+
166
+------------------------------------------------------------------
167
+
168
+ABACUS++T_3.0 [published 1 Nov 2011]
169
+
170
+New, simpler logic for descendents: the hole positions are scanned immediately
171
+upon creation of a new particle-hole pair; the hole positions are then kept fixed
172
+in subsequent descending.
173
+
174
+Problems:
175
+- when scanning for a function such as the one-body function for Lieb-Liniger,
176
+the extra particle in the AveragingState is not scanned to. Version 4 will
177
+address this problem.
178
+
179
+------------------------------------------------------------------
180
+
181
+ABACUS++T_4.0 [published 1 Nov 2011]
182
+
183
+Modification to the labeling logic:
184
+states are now always labeled using the AveragingState's quantum numbers,
185
+even if their bases are different. The form of the State_Label is thus changed.
186
+
187
+------------------------------------------------------------------
188
+
189
+ABACUS++T_5.0 [published 4 Nov 2011]
190
+
191
+Introduced two types of threads, separating scanning over fixed particle-hole numbers
192
+and adding a p-h.
193
+
194
+------------------------------------------------------------------
195
+
196
+ABACUS++T_6.0 [published 21 Nov 2011]
197
+
198
+The scanning is now also done over the hole positions.
199
+Upon the creation of a particle-hole, only hole positions at the edges of
200
+blocks of contiguous Ix2 in OriginState are used.
201
+The holes are then scanned moving towards the center of the blocks.
202
+
203
+There are now thus 3 types of scanning:
204
+0: over holes
205
+1: over particles
206
+2: adding a p-h pair
207
+
208
+------------------------------------------------------------------
209
+
210
+ABACUS++T_7.0 [published 1 Dec 2011]]
211
+
212
+Optimization of runtime memory use and of output files sizes.
213
+
214
+Labels: introduction of compressed labels (used in raw and thr files).
215
+Removed conv boolean from raw file (all states in this file have converged).
216
+Threads: removed omega and iK (changed General_Scan accordingly), use compressed labels.
217
+
218
+Scanning function: it's now possible to give a default file name when invoking
219
+General_Scan (and thus Scan_Bose, etc). This is done to avoid stupidly long file
220
+names when calculating correlators over AveragingStates which are far from
221
+the ground state.
222
+
223
+------------------------------------------------------------------
224
+
225
+ABACUS++T_8.0
226
+
227
+Changed labels slightly, to avoid identifying empty string with integer 0.
228
+All labels with at least one excitation are now strictly nonempty.
229
+
230
+
231
+------------------------------------------------------------------
232
+
233
+ABACUS++T_9 [in development][abandoned]
234
+
235
+Scanning over ensembles.

+ 122
- 0
include/JSC.h View File

@@ -0,0 +1,122 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC.h
10
+
11
+Purpose:  Core header file, includes all descendents.
12
+
13
+
14
+***********************************************************/
15
+
16
+#ifndef _JSC_H_
17
+#define _JSC_H_
18
+
19
+// This core header file includes all the others
20
+
21
+const char JSC_VERSION[20] = "ABACUS++G_8";
22
+
23
+// Standard includes
24
+#include <cmath>    
25
+#include <complex>  // for complex number algebra
26
+#include <string>
27
+
28
+#include <iostream>
29
+#include <fstream> 
30
+#include <iomanip>
31
+
32
+#include <cstdlib>  // for exit(), ...
33
+#include <ctime>    // for clock(), ...
34
+#include <limits>   // for numeric limits
35
+#include <climits>   // for numeric limits
36
+
37
+// For file sizes, etc
38
+#include "sys/types.h"
39
+#include "sys/stat.h"
40
+#include "unistd.h"
41
+
42
+// Signal handling
43
+#include <stdio.h>     /* standard I/O functions                         */
44
+#include <unistd.h>    /* standard unix functions, like getpid()         */
45
+#include <sys/types.h> /* various type definitions, like pid_t           */
46
+#include <signal.h>    /* signal name macros, and the signal() prototype */
47
+
48
+// My own math functions and shortcuts
49
+#include "JSC_util.h"
50
+
51
+// Vectors and matrices
52
+#include "JSC_Vect.h"   // My vector class definitions
53
+#include "JSC_Matrix.h"  // My matrix class definitions
54
+
55
+// Choose_Table
56
+#include "JSC_Combi.h"
57
+
58
+// Fitting, interpolating
59
+#include "JSC_Fitting.h"
60
+
61
+// Young tableaux
62
+#include "JSC_Young.h" 
63
+
64
+// Integration
65
+#include "JSC_Integ.h"
66
+
67
+// Special functions:
68
+#include "JSC_Spec_Fns.h"
69
+
70
+//***  Integrable models:
71
+
72
+// Heisenberg spin-1/2 antiferromagnet
73
+#include "JSC_Heis.h"      
74
+
75
+// Lieb-Liniger
76
+#include "JSC_LiebLin.h" 
77
+
78
+// One-d spinless fermions:
79
+#include "JSC_ODSLF.h"
80
+
81
+// General:
82
+//#include "JSC_Bethe.h"
83
+
84
+// Thermodynamic Bethe Ansatz utilities
85
+#include "JSC_TBA.h"
86
+
87
+// State ensembles
88
+#include "JSC_State_Ensemble.h"
89
+
90
+// XXX in zero field:  Uq(sl(2)) stuff
91
+#include "JSC_XXX_h0.h"
92
+
93
+// XXZ in zero field:  quantum groups
94
+#include "JSC_XXZ_h0.h"
95
+
96
+// Two-component Bose gas
97
+//#include "2CBG.h"
98
+
99
+// Richardson 
100
+//#include "Richardson.h"
101
+
102
+// *** Correlation functions:
103
+
104
+// New scanning protocols for ABACUS++
105
+#include "JSC_Scan.h"
106
+
107
+// Functions for everybody
108
+//#include "JSC_fns.h"            // KEEP THIS INCLUDE LAST, SINCE IT USES PREVIOUS DECLARATIONS
109
+
110
+// Numerical RG:
111
+#include "JSC_NRG.h"
112
+
113
+// OpenMP 
114
+#include <omp.h>
115
+
116
+// Typedefs:
117
+typedef double DP;
118
+
119
+
120
+#endif // _JSC_H_
121
+
122
+

+ 109
- 0
include/JSC_Bethe.h View File

@@ -0,0 +1,109 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_Bethe.h
10
+
11
+Purpose:  Declares Bethe state-related classes and functions.
12
+
13
+***********************************************************/
14
+
15
+#ifndef _BETHE_
16
+#define _BETHE_
17
+
18
+#include "JSC.h"
19
+
20
+namespace JSC {
21
+
22
+  /*
23
+  class Model {
24
+
25
+  protected:
26
+    string Name;  // LiebLin, XXZ, XXX, XXZ_gpd
27
+    int Nsites;   // 
28
+    int L;
29
+    DP interaction;
30
+
31
+  public:
32
+    Model (string Name_ref, 
33
+  };
34
+  */
35
+
36
+
37
+  class Base {
38
+
39
+  public:
40
+    int charge;        // charge of the base:  number of particles (LiebLin gas), number of down spins (Heis), ...
41
+    Vect<int> Nrap;    // Nrap[i] contains the number of rapidities of type i, i = 0, ..., Nstrings - 1.
42
+    int Nraptot;       // total number of strings in this state
43
+    Vect<DP> Ix2_infty;  // Ix2_infty[i] contains the max of BAE function for the (half-)integer I[i], i = 0, Nstrings - 1.
44
+    Vect<int> Ix2_min; 
45
+    Vect<int> Ix2_max;    // Ix2_max[i] contains the integer part of 2*I_infty, with correct parity for base.
46
+    string baselabel;
47
+
48
+  public:
49
+    Base ();
50
+    Base (const Base& RefBase);   // copy constructor
51
+
52
+  public:   // LiebLin constructors
53
+    Base (int N);       // Constructor for repulsive LiebLin gas case:  one type of particle
54
+    
55
+  public:   // HEIS constructors
56
+    //Base (const Heis_Chain& RefChain, int M);  // constructs configuration with all Mdown in one-string of +1 parity // DEPRECATED
57
+    Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities);  // sets to Nrapidities vector, and checks consistency
58
+    Base (const Heis_Chain& RefChain, string baselabel_ref);
59
+    
60
+  public:    // operators    
61
+    Base& operator= (const Base& RefBase);
62
+    bool operator== (const Base& RefBase);
63
+    bool operator!= (const Base& RefBase);
64
+
65
+  public:    // member functions
66
+    void Compute_Ix2_limits(const Heis_Chain& RefChain);  // computes the Ix2_infty and Ix2_max 
67
+  };    
68
+
69
+
70
+  //****************************************************************************
71
+
72
+  // Class Bethe_State is a wrapper class for all types of eigenstates
73
+
74
+  class Bethe_State {
75
+
76
+  public:   // configuration
77
+    Base base;
78
+    Vect<Vect<int> > Ix2;
79
+    Vect<Vect<DP> > lambda;
80
+
81
+  public:   // properties
82
+    DP E;
83
+    int iK;
84
+    DP K;
85
+    DP lnnorm;
86
+  
87
+  public:   // identification
88
+    string label;  // this is the relative label by default
89
+    Vect<Vect<int> > OriginIx2; // to define the relative label
90
+
91
+  public:   // convergence
92
+    DP diffsq;
93
+    int conv;
94
+    int iter;
95
+    int iter_Newton;
96
+
97
+    //public:  // for descendents, etc
98
+
99
+  public:   // constructors
100
+    Bethe_State();
101
+    Bethe_State (const Bethe_State& RefState);  // copy constructor
102
+    Bethe_State (const Bethe_State& OriginState, string label_ref);  
103
+
104
+    LiebLin_Bethe_State& operator= (const LiebLin_Bethe_State& RefState);
105
+
106
+
107
+} // namespace JSC
108
+
109
+#endif

+ 51
- 0
include/JSC_Combi.h View File

@@ -0,0 +1,51 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c) 2006-9.
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_Combi.h
10
+
11
+Purpose:  Declares combinatorics-related classes and functions.
12
+
13
+Last modified:  08/10/2009
14
+
15
+***********************************************************/
16
+
17
+#ifndef _COMBI_
18
+#define _COMBI_
19
+
20
+#include "JSC.h"
21
+
22
+namespace JSC {
23
+
24
+  //***********************************************************************
25
+
26
+  class Choose_Table {
27
+
28
+  private:
29
+    int Npower;
30
+    int Npowerp1;
31
+    int dim;
32
+    unsigned long long int* table;
33
+    void Fill_table ();
34
+
35
+  public:
36
+    Choose_Table ();
37
+    Choose_Table (int Npower_ref);
38
+    Choose_Table (const Choose_Table& Ref_Choose_Table); // constructs a new object from an existing one
39
+    int power();  // returns Npower
40
+    unsigned long long int choose (int N, int M);
41
+    ~Choose_Table ();
42
+
43
+  };
44
+
45
+
46
+  std::ostream& operator<< (std::ostream& s, Choose_Table& Ref_table);
47
+
48
+
49
+} // namespace JSC
50
+
51
+#endif

+ 37
- 0
include/JSC_Fitting.h View File

@@ -0,0 +1,37 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC.h
10
+
11
+Purpose:  Core header file, includes all descendents.
12
+
13
+***********************************************************/
14
+
15
+#ifndef _FITTING_
16
+#define _FITTING_
17
+
18
+namespace JSC {
19
+
20
+  // Functions in src/FITTING directory
21
+  void covsrt (SQMat_DP& covar, Vect<bool>& ia, const int mfit);
22
+  void lin_reg (Vect_DP x, Vect_DP y, Vect_DP sigma, DP& a, DP& b, DP& chisq);
23
+  void lin_reg (Vect_DP x, Vect_DP y, DP& a, DP& b, DP& chisq);
24
+  void mrqmin (Vect_DP& x, Vect_DP& y, Vect_DP& sig, Vect_DP& a, 
25
+	       Vect<bool>& ia, SQMat_DP& covar, SQMat_DP& alpha, DP& chisq,
26
+	       void funcs(const DP, Vect_DP&, DP&, Vect_DP&), DP& alambda);
27
+  void mrqcof (Vect_DP& x, Vect_DP& y, Vect_DP& sig, Vect_DP& a,
28
+	       Vect<bool>& ia, SQMat_DP& alpha, Vect_DP& beta, DP& chisq,
29
+	       void funcs (const DP, Vect_DP&, DP&, Vect_DP&));
30
+
31
+  // For interpolating:
32
+  void polint(Vect_DP& xa, Vect_DP& ya, const DP x, DP& y, DP& dy);
33
+  void polint(Vect_CX& xa, Vect_CX& ya, const complex<DP> x, complex<DP>& y, complex<DP>& dy);
34
+
35
+} // namespace JSC
36
+
37
+#endif

+ 777
- 0
include/JSC_Heis.h View File

@@ -0,0 +1,777 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c) 
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Heis.h
10
+
11
+Purpose:  Declares Heisenberg chain classes and functions.
12
+
13
+
14
+
15
+***********************************************************/
16
+
17
+#ifndef _HEIS_
18
+#define _HEIS_
19
+
20
+#include "JSC.h"
21
+
22
+namespace JSC {
23
+
24
+  // First, some global constants...
25
+
26
+  const long long int ID_UPPER_LIMIT = 10000000LL;  // max size of vectors we can define without seg fault
27
+  const int INTERVALS_SIZE = 100000;                // size of Scan_Intervals arrays
28
+  const int NBASESMAX = 1000; // max number of bases kept 
29
+
30
+  const DP ITER_REQ_PREC = 100.0 * MACHINE_EPS_SQ;
31
+  //const DP ITER_REQ_PREC = MACHINE_EPS_SQ;
32
+
33
+  // Cutoffs on particle numbers
34
+  //const int NPARTICLES_MAX = 24;
35
+  //const int NHOLES_MAX = NPARTICLES_MAX/2;
36
+  //const int MAX_RAPS_ABOVE_ZERO = 10;  // max nr of rapidities above lowest type
37
+  //const int NPARTICLES_MAX = 2;
38
+  //const int NHOLES_MAX = 1;
39
+  //const int MAX_TYPES_IN_BASE = 4;      // maximal number of particle types we allow in bases
40
+  const int MAXSTRINGS = 20;      // maximal number of particle types we allow in bases
41
+  //const int MAXSTRINGS = 2;      // maximal number of particle types we allow in bases
42
+  //const DP HEIS_deltaprec = 1.0e-6;//1.0e-4;  // maximal string deviation allowed // DEPRECATED in ++T_9
43
+
44
+  const int NEXC_MAX_HEIS = 16; // maximal number of excitations (string binding/unbinding, particle-hole) considered
45
+
46
+  //***********************************************************************
47
+
48
+  class Heis_Chain {
49
+
50
+  public:
51
+    DP J;
52
+    DP Delta;
53
+    DP anis;  // acos(Delta) if Delta < 1.0, 0 if Delta == 1.0, acosh(Delta) if Delta > 1.0
54
+    DP hz;  
55
+    int Nsites;
56
+    int Nstrings;  // how many possible strings.  The following two arrays have Nstrings nonzero elements. 
57
+    int* Str_L; // vector (length M) containing the allowed string lengths.  Elements that are 0 have no meaning.
58
+    int* par;    // vector (length M) containing the parities of the strings.  Elements that are 0 have no meaning.
59
+                  // Parities are all +1 except for gapless XXZ subcases
60
+    DP* si_n_anis_over_2;  // for optimization: sin for XXZ, sinh for XXZ_gpd
61
+    DP* co_n_anis_over_2;  // for optimization
62
+    DP* ta_n_anis_over_2;  // for optimization
63
+    DP prec;  // precision required for computations, always put to ITER_REQ_PREC
64
+
65
+  public:
66
+    Heis_Chain (); 
67
+    Heis_Chain (DP JJ, DP DD, DP hh, int NN);  // contructor:  simply initializes
68
+    Heis_Chain (const Heis_Chain& RefChain);            // copy constructor;
69
+    Heis_Chain& operator= (const Heis_Chain& RefChain); 
70
+    bool operator== (const Heis_Chain& RefChain);
71
+    bool operator!= (const Heis_Chain& RefChain);
72
+    ~Heis_Chain();  // destructor
73
+
74
+  public:
75
+    //void Scan_for_Possible_Bases (int Mdown, Vect<long long int>& possible_base_id, int& nfound, int nexc_max_used, 
76
+    //				  int base_level_to_scan, Vect<int>& Nrapidities);
77
+    //Vect<long long int> Possible_Bases (int Mdown);  // returns a vector of possible bases
78
+    /* Deactivated in ++G_8
79
+    void Scan_for_Possible_Bases (int Mdown, Vect<string>& possible_base_label, int& nfound, int nexc_max_used, 
80
+    				  int base_level_to_scan, Vect<int>& Nrapidities);
81
+    Vect<string> Possible_Bases (int Mdown);  // returns a vector of possible bases
82
+    */
83
+  };
84
+
85
+  //****************************************************************************
86
+
87
+  // Objects in class Heis_Base are a checked vector containing the number of rapidities of allowable types for a given state
88
+
89
+  class Heis_Base {
90
+
91
+  public:
92
+    int Mdown;         // total number of down spins
93
+    Vect<int> Nrap;    // Nrap[i] contains the number of rapidities of type i, i = 0, Nstrings - 1.
94
+    int Nraptot;       // total number of strings in this state
95
+    Vect<DP> Ix2_infty;  // Ix2_infty[i] contains the max of BAE function for the (half-)integer I[i], i = 0, Nstrings - 1.
96
+    Vect<int> Ix2_min;
97
+    Vect<int> Ix2_max;    // Ix2_max[i] contains the integer part of 2*I_infty, with correct parity for base.
98
+    //long long int id;  // identification number
99
+    double dimH;          // dimension of sub Hilbert space associated to this base; use double to avoid max int problems.
100
+    string baselabel;      // base label
101
+
102
+  public:
103
+    Heis_Base ();
104
+    Heis_Base (const Heis_Base& RefBase);  // copy constructor
105
+    Heis_Base (const Heis_Chain& RefChain, int M);  // constructs configuration with all Mdown in one-string of +1 parity
106
+    Heis_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities);  // sets to Nrapidities vector, and checks consistency
107
+    //Heis_Base (const Heis_Chain& RefChain, long long int id_ref);
108
+    Heis_Base (const Heis_Chain& RefChain, string baselabel_ref);
109
+    inline int& operator[] (const int i);
110
+    inline const int& operator[] (const int i) const; 
111
+    Heis_Base& operator= (const Heis_Base& RefBase);
112
+    bool operator== (const Heis_Base& RefBase);
113
+    bool operator!= (const Heis_Base& RefBase);
114
+
115
+    void Compute_Ix2_limits(const Heis_Chain& RefChain);  // computes the Ix2_infty and Ix2_max 
116
+
117
+    //void Scan_for_Possible_Types (Vect<long long int>& possible_type_id, int& nfound, int base_level, Vect<int>& Nexcitations);
118
+    //Vect<long long int> Possible_Types ();  // returns a vector of possible types
119
+
120
+  };
121
+
122
+  inline int& Heis_Base::operator[] (const int i)
123
+  {
124
+    return Nrap[i];
125
+  }
126
+  
127
+  inline const int& Heis_Base::operator[] (const int i) const
128
+  {
129
+    return Nrap[i];
130
+  }
131
+
132
+  //****************************************************************************
133
+  /*
134
+  // Objects in class Ix2_Config carry all the I's of a given state
135
+
136
+  class Ix2_Config {
137
+
138
+    //private:
139
+  public:
140
+    int Nstrings;
141
+    Vect<int> Nrap;
142
+    int Nraptot;
143
+
144
+    //int** Ix2;
145
+    Vect<Vect<int> > Ix2;
146
+
147
+  public:
148
+    Ix2_Config ();
149
+    Ix2_Config (const Heis_Chain& RefChain, int M);   // constructor, puts I's to ground state
150
+    Ix2_Config (const Heis_Chain& RefChain, const Heis_Base& base);   // constructor, putting I's to lowest-energy config 
151
+                                                               // consistent with Heis_Base configuration for chain RefChain
152
+    Ix2_Config& operator= (const Ix2_Config& RefConfig);
153
+    //inline int* operator[] (const int i);
154
+    inline Vect<int> operator[] (const int i); 
155
+    //inline const int* operator[] (const int i) const;
156
+    inline const Vect<int> operator[] (const int i) const; 
157
+    //~Ix2_Config(); // not needed, inherited from Vect
158
+    string Return_Label (const Ix2_Config& OriginIx2);
159
+  };
160
+
161
+  //inline int* Ix2_Config::operator[] (const int i)
162
+  inline Vect<int> Ix2_Config::operator[] (const int i)
163
+    {
164
+      return Ix2[i];
165
+    }
166
+  
167
+  //inline const int* Ix2_Config::operator[] (const int i) const
168
+  inline const Vect<int> Ix2_Config::operator[] (const int i) const
169
+  {
170
+    return Ix2[i];
171
+  }
172
+
173
+  std::ostream& operator<< (std::ostream& s, const Ix2_Config& RefConfig);
174
+  */
175
+  //****************************************************************************
176
+
177
+  // Objects in class Lambda carry all rapidities of a state
178
+
179
+  class Lambda {
180
+    
181
+  private:
182
+    int Nstrings;
183
+    Vect<int> Nrap;
184
+    int Nraptot;
185
+    DP** lambda;
186
+    //Vect<Vect<DP> > lambda;
187
+    
188
+  public:
189
+    Lambda ();
190
+    Lambda (const Heis_Chain& RefChain, int M);   // constructor, puts all lambda's to zero
191
+    Lambda (const Heis_Chain& RefChain, const Heis_Base& base);   // constructor, putting I's to lowest-energy config 
192
+    // consistent with Heis_Base configuration for chain RefChain
193
+    Lambda& operator= (const Lambda& RefConfig);
194
+    inline DP* operator[] (const int i);
195
+    //inline Vect<DP> operator[] (const int i);
196
+    inline const DP* operator[] (const int i) const;
197
+    //inline const Vect<DP> operator[] (const int i) const;
198
+    ~Lambda();
199
+
200
+  };
201
+
202
+  inline DP* Lambda::operator[] (const int i)
203
+  //inline Vect<DP> Lambda::operator[] (const int i)
204
+    {
205
+      return lambda[i];
206
+    }
207
+  
208
+  inline const DP* Lambda::operator[] (const int i) const
209
+  //inline const Vect<DP> Lambda::operator[] (const int i) const
210
+    {
211
+      return lambda[i];
212
+    }
213
+
214
+
215
+  //****************************************************************************
216
+
217
+  // Objects in class Ix2_Offsets carry Young tableau representations of the Ix2 configurations
218
+  /*
219
+  class Ix2_Offsets {
220
+
221
+  public:
222
+    Heis_Base base;
223
+    Vect<Young_Tableau> Tableau;  // vector of pointers to tableaux at each level
224
+    long long int type_id;
225
+    long long int id;        // id number of offset
226
+    long long int maxid;     // max id number allowable
227
+
228
+  public:
229
+    Ix2_Offsets ();
230
+    Ix2_Offsets (const Ix2_Offsets& RefOffset);  // copy constructor
231
+    Ix2_Offsets (const Heis_Base& RefBase, long long int req_type_id);
232
+    Ix2_Offsets (const Heis_Base& RefBase, Vect<int> nparticles);  // sets all tableaux to empty ones, with nparticles[] at each level
233
+    Ix2_Offsets& operator= (const Ix2_Offsets& RefOffset);
234
+    bool operator<= (const Ix2_Offsets& RefOffsets);
235
+    bool operator>= (const Ix2_Offsets& RefOffsets);
236
+
237
+  public:
238
+    void Set_to_id (long long int idnr);  
239
+    void Compute_id ();
240
+    void Compute_type_id ();
241
+
242
+  public:
243
+    bool Add_Boxes_From_Lowest (int Nboxes, bool odd_sectors); // adds Nboxes in minimal energy config, all boxes in either even or odd sectors
244
+
245
+  };
246
+
247
+  inline long long int Ix2_Offsets_type_id (Vect<int>& nparticles)
248
+    {
249
+      long long int type_id_here = 0ULL;
250
+
251
+      for (int i = 0; i < nparticles.size(); ++i)
252
+	type_id_here += nparticles[i] * pow_ulli(10ULL, i);
253
+
254
+      return(type_id_here);
255
+    }
256
+
257
+  long long int Find_idmin (Ix2_Offsets& scan_offsets, int particle_type, int tableau_level, int Row_L_min);
258
+  long long int Find_idmax (Ix2_Offsets& scan_offsets, int particle_type, int tableau_level);
259
+  */
260
+  //****************************************************************************
261
+  // Objects in class Ix2_Offsets_List carry a vector of used Ix2_Offsets
262
+  /*
263
+  class Ix2_Offsets_List {
264
+
265
+  public:
266
+    int ndef;
267
+    Vect<Ix2_Offsets> Offsets;
268
+
269
+  public:
270
+    Ix2_Offsets_List ();
271
+    Ix2_Offsets& Return_Offsets (Heis_Base& RefBase, Vect<int> nparticles);  // returns the Ix2_Offsets corresponding to nparticles[]/base
272
+    Ix2_Offsets& Return_Offsets (Heis_Base& RefBase, long long int req_type_id);
273
+  };
274
+  */
275
+  //****************************************************************************
276
+
277
+  // Objects in class Heis_Bethe_State carry all information about an eigenstate
278
+
279
+  // Derived classes include XXZ_Bethe_State, XXX_Bethe_State, XXZ_gpd_Bethe_State
280
+  // These contain subclass-specific functions and data.
281
+
282
+  class Heis_Bethe_State {
283
+    
284
+  public:
285
+    Heis_Chain chain;
286
+    Heis_Base base;
287
+    //Ix2_Offsets offsets;
288
+    //Ix2_Config Ix2;
289
+    Vect<Vect<int> > Ix2;
290
+    Lambda lambda;
291
+    Lambda deviation;      // string deviations
292
+    Lambda BE;             // Bethe equation for relevant rapidity, in the form BE = theta - (1/N)\sum ... - \pi I/N = 0
293
+    DP diffsq;             // sum of squares of rapidity differences in last iteration 
294
+    int conv;              // convergence status
295
+    DP dev;                // sum of absolute values of string deviations
296
+    int iter;              // number of iterations necessary for convergence
297
+    int iter_Newton;              // number of iterations necessary for convergence (Newton method)
298
+    DP E;                  // total energy
299
+    int iK;                // K = 2.0*PI * iK/Nsites
300
+    DP K;                  // total momentum
301
+    DP lnnorm;             // ln of norm of reduced Gaudin matrix
302
+    //long long int base_id;
303
+    //long long int type_id;
304
+    //long long int id;
305
+    //long long int maxid;
306
+    //int nparticles;
307
+    string label;
308
+
309
+  public:
310
+    Heis_Bethe_State (); 
311
+    Heis_Bethe_State (const Heis_Bethe_State& RefState);  // copy constructor
312
+    //Heis_Bethe_State (const Heis_Bethe_State& RefState, long long int type_id_ref);  // new state with requested type_id
313
+    Heis_Bethe_State (const Heis_Chain& RefChain, int M);  // constructor to ground-state configuration
314
+    Heis_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base);  // constructor to lowest-energy config with base
315
+    //Heis_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref);  
316
+    virtual ~Heis_Bethe_State () {};
317
+
318
+  public:
319
+    int Charge () { return(base.Mdown); }; 
320
+    //void Set_Ix2_Offsets (const Ix2_Offsets& RefOffset);  // sets the Ix2 to given offsets
321
+    //void Set_to_id (long long int id_ref);
322
+    //void Set_to_id (long long int id_ref, Heis_Bethe_State& RefState);
323
+    //int Nparticles (); // counts the number of particles in state once Ix2 offsets set (so type_id is correctly set)
324
+    //void Set_to_Label (string label_ref, const Ix2_Config& OriginIx2); 
325
+    void Set_to_Label (string label_ref, const Vect<Vect<int> >& OriginIx2); 
326
+    void Set_Label_from_Ix2 (const Vect<Vect<int> >& OriginIx2); 
327
+    bool Check_Symmetry ();  // checks whether the I's are symmetrically distributed
328
+    void Compute_diffsq ();  // \sum BE[j][alpha]^2
329
+    void Find_Rapidities (bool reset_rapidities);  // Finds the rapidities
330
+    void Find_Rapidities_Twisted (bool reset_rapidities, DP twist);  // Finds the rapidities with twist added to RHS of logBE
331
+    //void BAE_smackdown (DP max_allowed);
332
+    //void Solve_BAE_smackdown (DP max_allowed, int maxruns);
333
+    void Solve_BAE_bisect (int j, int alpha, DP req_prec, int itermax);
334
+    void Iterate_BAE (DP iter_factor);     // Finds new set of lambda[j][alpha] from previous one by simple iteration
335
+    void Solve_BAE_straight_iter (DP straight_prec, int max_iter_interp, DP iter_factor);
336
+    void Solve_BAE_extrap (DP extrap_prec, int max_iter_extrap, DP iter_factor);
337
+    void Iterate_BAE_Newton ();     // Finds new set of lambda[j][alpha] from previous one by a Newton step
338
+    void Solve_BAE_Newton (DP Newton_prec, int max_iter_Newton);
339
+    void Solve_BAE_with_silk_gloves (DP silk_prec, int max_iter_silk, DP iter_factor);
340
+    void Compute_lnnorm ();
341
+    void Compute_Momentum ();
342
+    void Compute_All (bool reset_rapidities);     // solves BAE, computes E, K and lnnorm
343
+
344
+    inline bool Set_to_Inner_Skeleton (int iKneeded, const Vect<Vect<int> >& OriginStateIx2)
345
+    {
346
+      Ix2[0][0] = Ix2[0][1] - 2;
347
+      Ix2[0][base.Nrap[0] - 1] = Ix2[0][base.Nrap[0] - 2] + 2;
348
+      (*this).Compute_Momentum();
349
+      if (base.Nrap[0] == 0) return(false);
350
+      if (iKneeded >= iK) Ix2[0][base.Nrap[0]-1] += 2*(iKneeded - iK);
351
+      else Ix2[0][0] += 2*(iKneeded - iK);
352
+      if (Ix2[0][0] < base.Ix2_min[0] || Ix2[0][base.Nrap[0]-1] > base.Ix2_max[0]) return(false);
353
+      (*this).Set_Label_from_Ix2 (OriginStateIx2);
354
+      return(true);
355
+    }
356
+    void Set_to_Outer_Skeleton (const Vect<Vect<int> >& OriginStateIx2) { 
357
+      Ix2[0][0] = base.Ix2_min[0] - 4; 
358
+      Ix2[0][base.Nrap[0]-1] = base.Ix2_max[0] + 4; 
359
+      (*this).Set_Label_from_Ix2 (OriginStateIx2);
360
+    };
361
+
362
+    void Set_to_Closest_Matching_Ix2_fixed_Base (const Heis_Bethe_State& StateToMatch); // defined in Heis.cc
363
+
364
+
365
+    // Virtual functions, all defined in the derived classes
366
+
367
+  public:
368
+    virtual void Set_Free_lambdas() { JSCerror("Heis_Bethe_State::..."); }  // sets the rapidities to solutions of BAEs without scattering terms
369
+    virtual bool Check_Admissibility(char option) { JSCerror("Heis_Bethe_State::..."); return(false); }   
370
+    // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
371
+    virtual void Compute_BE (int j, int alpha) { JSCerror("Heis_Bethe_State::..."); }
372
+    virtual void Compute_BE () { JSCerror("Heis_Bethe_State::..."); }
373
+    virtual DP Iterate_BAE(int i, int alpha) { JSCerror("Heis_Bethe_State::..."); return(0.0);}
374
+    virtual bool Check_Rapidities() { JSCerror("Heis_Bethe_State::..."); return(false); }
375
+    virtual DP String_delta () { JSCerror("Heis_Bethe_State::..."); return(0.0); }
376
+    virtual void Compute_Energy () { JSCerror("Heis_Bethe_State::..."); }
377
+    virtual void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red) { JSCerror("Heis_Bethe_State::..."); }
378
+  };
379
+
380
+  inline bool Is_Inner_Skeleton (Heis_Bethe_State& State) { 
381
+    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)); 
382
+  }; 
383
+  inline bool Is_Outer_Skeleton (Heis_Bethe_State& State) { 
384
+    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); 
385
+  }; 
386
+  
387
+  inline bool Force_Descent (char whichDSF, Heis_Bethe_State& ScanState, Heis_Bethe_State& RefState, int desc_type_required, int iKmod, DP Chem_Pot)
388
+  {
389
+    bool force_descent = false;
390
+
391
+    // Force descent if energy of ScanState is lower than that of RefState
392
+    //if (ScanState.E - RefState.E - (ScanState.base.Mdown - RefState.base.Mdown) < 0.0) return(true); 
393
+    /*
394
+    // We force descent if 
395
+    // 1)  - there exists a higher string whose quantum number is still on 0
396
+    // AND - there is at most a single particle-hole in the 0 base level
397
+    // AND - either the particle or the hole hasn't yet moved.
398
+    if (ScanState.base_id/100000LL > 0) { // there is a higher string
399
+      int type0 = ScanState.type_id % 10000;
400
+      if (type0 == 0 
401
+	  || type0 == 101 && ScanState.offsets.Tableau[0].id * ScanState.offsets.Tableau[2].id == 0LL 
402
+	  || type0 == 110 && ScanState.offsets.Tableau[1].id * ScanState.offsets.Tableau[2].id == 0LL 
403
+	  || type0 == 1001 && ScanState.offsets.Tableau[0].id * ScanState.offsets.Tableau[3].id == 0LL 
404
+	  || type0 == 1010 && ScanState.offsets.Tableau[1].id * ScanState.offsets.Tableau[3].id == 0LL) // single p-h pair in base level 0
405
+	for (int j = 1; j < ScanState.chain.Nstrings; ++j) {
406
+	  if (ScanState.base[j] == 1 && ScanState.Ix2[j][0] == 0) {
407
+	    force_descent = true;
408
+	  }
409
+	}
410
+    }
411
+    */
412
+    // Force descent if quantum nr distribution is symmetric:
413
+    //if (ScanState.Check_Symmetry()) force_descent = true;
414
+    //if (desc_type_required > 8 && ScanState.Check_Symmetry()) force_descent = true;
415
+
416
+    // Force descent for longitudinal if we're at zero or pi momentum:
417
+    //ScanState.Compute_Momentum();
418
+    //if (whichDSF == 'z' && (ScanState.iK - RefState.iK) % iKmod == 0) force_descent = true;
419
+    //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
420
+    // Force descent for all DSFs if we're at K = 0 or PI and not conserving momentum upon descent:
421
+    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
422
+
423
+    //if (force_descent) cout << "Forcing descent on state with label " << ScanState.label << endl;
424
+
425
+    if (ScanState.chain.Delta > 1.0) {
426
+      /*
427
+      // Count the nr of holes in one-strings:
428
+      int nholes = 0;
429
+      for (int i = 0; i < ScanState.base.Nrap[0] - 1; ++i) if (ScanState.Ix2[0][i+1] - ScanState.Ix2[0][i] != 2) nholes++;
430
+      
431
+      if (nholes <= 2) {
432
+	if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 2 && ScanState.base.Nrap[1] == 1) force_descent = true;
433
+	if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 3 && ScanState.base.Nrap[2] == 1) force_descent = true;
434
+	if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 4 && ScanState.base.Nrap[1] == 2) force_descent = true;
435
+      }
436
+      */
437
+
438
+      if (ScanState.label.compare(0, 10, "14x1y1_0x0") == 0) force_descent = true;
439
+      if (ScanState.label.compare(0, 10, "14x1y1_0x1") == 0) force_descent = true;
440
+      if (ScanState.label.compare(0, 10, "14x1y1_1x0") == 0) force_descent = true;
441
+      if (ScanState.label.compare(0, 10, "14x1y1_1x1") == 0) force_descent = true;
442
+      if (ScanState.label.compare(0, 10, "14x1y1_2x0") == 0) force_descent = true;
443
+      if (ScanState.label.compare(0, 10, "14x1y1_2x1") == 0) force_descent = true;
444
+      if (ScanState.label.compare(0, 10, "12x1y2_0x0") == 0) force_descent = true;
445
+      if (ScanState.label.compare(0, 10, "12x1y2_0x1") == 0) force_descent = true;
446
+      if (ScanState.label.compare(0, 10, "12x1y2_0x2") == 0) force_descent = true;
447
+      if (ScanState.label.compare(0, 10, "12x1y2_1x0") == 0) force_descent = true;
448
+      if (ScanState.label.compare(0, 10, "12x1y2_1x1") == 0) force_descent = true;
449
+      if (ScanState.label.compare(0, 10, "12x1y2_1x2") == 0) force_descent = true;
450
+      if (ScanState.label.compare(0, 10, "12x1y2_2x0") == 0) force_descent = true;
451
+      if (ScanState.label.compare(0, 10, "12x1y2_2x1") == 0) force_descent = true;
452
+      if (ScanState.label.compare(0, 10, "12x1y2_2x2") == 0) force_descent = true;
453
+      if (ScanState.label.compare(0, 10, "13x2y1_0x0") == 0) force_descent = true;
454
+      if (ScanState.label.compare(0, 10, "13x2y1_0x1") == 0) force_descent = true;
455
+      if (ScanState.label.compare(0, 10, "13x2y1_1x0") == 0) force_descent = true;
456
+      if (ScanState.label.compare(0, 10, "13x2y1_1x1") == 0) force_descent = true;
457
+      if (ScanState.label.compare(0, 10, "13x2y1_2x0") == 0) force_descent = true;
458
+      if (ScanState.label.compare(0, 10, "13x2y1_2x1") == 0) force_descent = true;
459
+
460
+      if (ScanState.label.compare(0, 10, "30x1y1_0x0") == 0) force_descent = true;
461
+      if (ScanState.label.compare(0, 10, "30x1y1_0x1") == 0) force_descent = true;
462
+      if (ScanState.label.compare(0, 10, "30x1y1_1x0") == 0) force_descent = true;
463
+      if (ScanState.label.compare(0, 10, "30x1y1_1x1") == 0) force_descent = true;
464
+      if (ScanState.label.compare(0, 10, "30x1y1_2x0") == 0) force_descent = true;
465
+      if (ScanState.label.compare(0, 10, "30x1y1_2x1") == 0) force_descent = true;
466
+      if (ScanState.label.compare(0, 10, "28x1y2_0x0") == 0) force_descent = true;
467
+      if (ScanState.label.compare(0, 10, "28x1y2_0x1") == 0) force_descent = true;
468
+      if (ScanState.label.compare(0, 10, "28x1y2_0x2") == 0) force_descent = true;
469
+      if (ScanState.label.compare(0, 10, "28x1y2_1x0") == 0) force_descent = true;
470
+      if (ScanState.label.compare(0, 10, "28x1y2_1x1") == 0) force_descent = true;
471
+      if (ScanState.label.compare(0, 10, "28x1y2_1x2") == 0) force_descent = true;
472
+      if (ScanState.label.compare(0, 10, "28x1y2_2x0") == 0) force_descent = true;
473
+      if (ScanState.label.compare(0, 10, "28x1y2_2x1") == 0) force_descent = true;
474
+      if (ScanState.label.compare(0, 10, "28x1y2_2x2") == 0) force_descent = true;
475
+      if (ScanState.label.compare(0, 10, "29x2y1_0x0") == 0) force_descent = true;
476
+      if (ScanState.label.compare(0, 10, "29x2y1_0x1") == 0) force_descent = true;
477
+      if (ScanState.label.compare(0, 10, "29x2y1_1x0") == 0) force_descent = true;
478
+      if (ScanState.label.compare(0, 10, "29x2y1_1x1") == 0) force_descent = true;
479
+      if (ScanState.label.compare(0, 10, "29x2y1_2x0") == 0) force_descent = true;
480
+      if (ScanState.label.compare(0, 10, "29x2y1_2x1") == 0) force_descent = true;
481
+
482
+      if (ScanState.label.compare(0, 10, "46x1y1_0x0") == 0) force_descent = true;
483
+      if (ScanState.label.compare(0, 10, "46x1y1_0x1") == 0) force_descent = true;
484
+      if (ScanState.label.compare(0, 10, "46x1y1_1x0") == 0) force_descent = true;
485
+      if (ScanState.label.compare(0, 10, "46x1y1_1x1") == 0) force_descent = true;
486
+      if (ScanState.label.compare(0, 10, "46x1y1_2x0") == 0) force_descent = true;
487
+      if (ScanState.label.compare(0, 10, "46x1y1_2x1") == 0) force_descent = true;
488
+      if (ScanState.label.compare(0, 10, "44x1y2_0x0") == 0) force_descent = true;
489
+      if (ScanState.label.compare(0, 10, "44x1y2_0x1") == 0) force_descent = true;
490
+      if (ScanState.label.compare(0, 10, "44x1y2_0x2") == 0) force_descent = true;
491
+      if (ScanState.label.compare(0, 10, "44x1y2_1x0") == 0) force_descent = true;
492
+      if (ScanState.label.compare(0, 10, "44x1y2_1x1") == 0) force_descent = true;
493
+      if (ScanState.label.compare(0, 10, "44x1y2_1x2") == 0) force_descent = true;
494
+      if (ScanState.label.compare(0, 10, "44x1y2_2x0") == 0) force_descent = true;
495
+      if (ScanState.label.compare(0, 10, "44x1y2_2x1") == 0) force_descent = true;
496
+      if (ScanState.label.compare(0, 10, "44x1y2_2x2") == 0) force_descent = true;
497
+      if (ScanState.label.compare(0, 10, "45x2y1_0x0") == 0) force_descent = true;
498
+      if (ScanState.label.compare(0, 10, "45x2y1_0x1") == 0) force_descent = true;
499
+      if (ScanState.label.compare(0, 10, "45x2y1_1x0") == 0) force_descent = true;
500
+      if (ScanState.label.compare(0, 10, "45x2y1_1x1") == 0) force_descent = true;
501
+      if (ScanState.label.compare(0, 10, "45x2y1_2x0") == 0) force_descent = true;
502
+      if (ScanState.label.compare(0, 10, "45x2y1_2x1") == 0) force_descent = true;
503
+
504
+
505
+      if (ScanState.label.compare(0, 10, "62x1y1_0x0") == 0) force_descent = true;
506
+      if (ScanState.label.compare(0, 10, "62x1y1_0x1") == 0) force_descent = true;
507
+      if (ScanState.label.compare(0, 10, "62x1y1_1x0") == 0) force_descent = true;
508
+      if (ScanState.label.compare(0, 10, "62x1y1_1x1") == 0) force_descent = true;
509
+      if (ScanState.label.compare(0, 10, "62x1y1_2x0") == 0) force_descent = true;
510
+      //if (ScanState.label.compare(0, 10, "62x1y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
511
+      if (ScanState.label.compare(0, 10, "62x1y1_2x1") == 0 
512
+	  && (desc_type_required == 14 || desc_type_required == 13 || desc_type_required == 11 || desc_type_required == 10)) force_descent = true;
513
+      /*
514
+      if (ScanState.label.compare(0, 10, "60x1y2_0x0") == 0) force_descent = true;
515
+      if (ScanState.label.compare(0, 10, "60x1y2_0x1") == 0) force_descent = true;
516
+      if (ScanState.label.compare(0, 10, "60x1y2_0x2") == 0) force_descent = true;
517
+      if (ScanState.label.compare(0, 10, "60x1y2_1x0") == 0) force_descent = true;
518
+      if (ScanState.label.compare(0, 10, "60x1y2_1x1") == 0) force_descent = true;
519
+      if (ScanState.label.compare(0, 10, "60x1y2_1x2") == 0) force_descent = true;
520
+      if (ScanState.label.compare(0, 10, "60x1y2_2x0") == 0) force_descent = true;
521
+      if (ScanState.label.compare(0, 10, "60x1y2_2x1") == 0 && desc_type_required < 2) force_descent = true;
522
+      if (ScanState.label.compare(0, 10, "60x1y2_2x2") == 0 && desc_type_required < 2) force_descent = true;
523
+      if (ScanState.label.compare(0, 10, "61x2y1_0x0") == 0) force_descent = true;
524
+      if (ScanState.label.compare(0, 10, "61x2y1_0x1") == 0) force_descent = true;
525
+      if (ScanState.label.compare(0, 10, "61x2y1_1x0") == 0) force_descent = true;
526
+      if (ScanState.label.compare(0, 10, "61x2y1_1x1") == 0) force_descent = true;
527
+      if (ScanState.label.compare(0, 10, "61x2y1_2x0") == 0) force_descent = true;
528
+      if (ScanState.label.compare(0, 10, "61x2y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
529
+      */
530
+
531
+      if (ScanState.label.compare(0, 11, "126x1y1_0x0") == 0) force_descent = true;
532
+      if (ScanState.label.compare(0, 11, "126x1y1_0x1") == 0) force_descent = true;
533
+      if (ScanState.label.compare(0, 11, "126x1y1_1x0") == 0) force_descent = true;
534
+      if (ScanState.label.compare(0, 11, "126x1y1_1x1") == 0) force_descent = true;
535
+      if (ScanState.label.compare(0, 11, "126x1y1_2x0") == 0) force_descent = true;
536
+      //if (ScanState.label.compare(0, 11, "126x1y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
537
+      if (ScanState.label.compare(0, 11, "126x1y1_2x1") == 0 
538
+	  && (desc_type_required == 14 || desc_type_required == 13 || desc_type_required == 11 || desc_type_required == 10)) force_descent = true;
539
+      /*
540
+      if (ScanState.label.compare(0, 10, "124x1y2_0x0") == 0) force_descent = true;
541
+      if (ScanState.label.compare(0, 10, "124x1y2_0x1") == 0) force_descent = true;
542
+      if (ScanState.label.compare(0, 10, "124x1y2_0x2") == 0) force_descent = true;
543
+      if (ScanState.label.compare(0, 10, "124x1y2_1x0") == 0) force_descent = true;
544
+      if (ScanState.label.compare(0, 10, "124x1y2_1x1") == 0) force_descent = true;
545
+      if (ScanState.label.compare(0, 10, "124x1y2_1x2") == 0) force_descent = true;
546
+      if (ScanState.label.compare(0, 10, "124x1y2_2x0") == 0) force_descent = true;
547
+      if (ScanState.label.compare(0, 10, "124x1y2_2x1") == 0) force_descent = true;
548
+      if (ScanState.label.compare(0, 10, "124x1y2_2x2") == 0) force_descent = true;
549
+      if (ScanState.label.compare(0, 10, "125x2y1_0x0") == 0) force_descent = true;
550
+      if (ScanState.label.compare(0, 10, "125x2y1_0x1") == 0) force_descent = true;
551
+      if (ScanState.label.compare(0, 10, "125x2y1_1x0") == 0) force_descent = true;
552
+      if (ScanState.label.compare(0, 10, "125x2y1_1x1") == 0) force_descent = true;
553
+      if (ScanState.label.compare(0, 10, "125x2y1_2x0") == 0) force_descent = true;
554
+      if (ScanState.label.compare(0, 10, "125x2y1_2x1") == 0) force_descent = true;
555
+      */
556
+      if (ScanState.label.compare(0, 11, "254x1y1_0x0") == 0) force_descent = true;
557
+      if (ScanState.label.compare(0, 11, "254x1y1_0x1") == 0) force_descent = true;
558
+      if (ScanState.label.compare(0, 11, "254x1y1_1x0") == 0) force_descent = true;
559
+      if (ScanState.label.compare(0, 11, "254x1y1_1x1") == 0) force_descent = true;
560
+      if (ScanState.label.compare(0, 11, "254x1y1_2x0") == 0) force_descent = true;
561
+      if (ScanState.label.compare(0, 11, "254x1y1_2x1") == 0 && desc_type_required < 2) force_descent = true;
562
+
563
+      // Do not force descent a state with rapidities outside of fundamental interval:
564
+      /*
565
+      for (int j = 0; j < ScanState.chain.Nstrings; ++j) {
566
+	// Logic: allow rapidities -PI/2 <= lambda <= PI/2 (including boundaries)
567
+	if (ScanState.base.Nrap[j] > 0 && 
568
+	    (ScanState.lambda[j][0] < -PI/2 || ScanState.lambda[j][ScanState.base.Nrap[j] - 1] > PI/2))
569
+	  force_descent = false;
570
+	
571
+	// rapidities should also be ordered as the quantum numbers:
572
+	for (int alpha = 1; alpha < ScanState.base.Nrap[j]; ++alpha)
573
+	  if (ScanState.lambda[j][alpha - 1] >= ScanState.lambda[j][alpha])
574
+	    force_descent = false;
575
+      }
576
+      */
577
+      //if (force_descent) cout << "Forcing descent on state with label " << ScanState.label << endl;
578
+    } // if Delta > 1
579
+
580
+    //if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 2 && ScanState.base.Nrap[1] == 1 && ScanState.Ix2[1][0] == 0) force_descent = true;
581
+    //if (ScanState.base.Nrap[0] == ScanState.base.Mdown - 3 && ScanState.base.Nrap[2] == 1 && ScanState.Ix2[2][0] == 0) force_descent = true;
582
+    //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;
583
+
584
+    return(force_descent);
585
+  }
586
+
587
+  std::ostream& operator<< (std::ostream& s, const Heis_Bethe_State& state);
588
+
589
+  //****************************************************************************
590
+
591
+  // Objects in class XXZ_Bethe_State carry all extra information pertaining to XXZ gapless
592
+
593
+  class XXZ_Bethe_State : public Heis_Bethe_State {
594
+    
595
+  public:
596
+    Lambda sinhlambda;  
597
+    Lambda coshlambda;  
598
+    Lambda tanhlambda;  
599
+
600
+  public:
601
+    XXZ_Bethe_State (); 
602
+    XXZ_Bethe_State (const XXZ_Bethe_State& RefState);  // copy constructor
603
+    XXZ_Bethe_State (const Heis_Chain& RefChain, int M);  // constructor to ground-state configuration
604
+    XXZ_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base);  // constructor to lowest-energy config with base
605
+    //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
606
+
607
+  public:
608
+    XXZ_Bethe_State& operator= (const XXZ_Bethe_State& RefState);
609
+    
610
+  public:
611
+    void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
612
+    void Compute_sinhlambda();
613
+    void Compute_coshlambda();
614
+    void Compute_tanhlambda();
615
+    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.
616
+    void Compute_BE (int j, int alpha);
617
+    void Compute_BE ();
618
+    DP Iterate_BAE(int i, int j);
619
+    bool Check_Rapidities();  // checks that all rapidities are not nan
620
+    DP String_delta ();
621
+    void Compute_Energy ();
622
+    //void Compute_Momentum ();
623
+    void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);    
624
+
625
+    // XXZ specific functions:
626
+  public:
627
+
628
+  };
629
+
630
+  XXZ_Bethe_State Add_Particle_at_Center (const XXZ_Bethe_State& RefState);
631
+  XXZ_Bethe_State Remove_Particle_at_Center (const XXZ_Bethe_State& RefState);
632
+
633
+  //****************************************************************************
634
+
635
+  // Objects in class XXX_Bethe_State carry all extra information pertaining to XXX antiferromagnet
636
+
637
+  class XXX_Bethe_State : public Heis_Bethe_State {
638
+
639
+  public:
640
+    XXX_Bethe_State (); 
641
+    XXX_Bethe_State (const XXX_Bethe_State& RefState);  // copy constructor
642
+    XXX_Bethe_State (const Heis_Chain& RefChain, int M);  // constructor to ground-state configuration
643
+    XXX_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base);  // constructor to lowest-energy config with base
644
+    //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
645
+
646
+  public:
647
+    XXX_Bethe_State& operator= (const XXX_Bethe_State& RefState);
648
+
649
+  public:
650
+    void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
651
+    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.
652
+    void Compute_BE (int j, int alpha);
653
+    void Compute_BE ();
654
+    DP Iterate_BAE(int i, int j);
655
+    bool Check_Rapidities();  // checks that all rapidities are not nan    
656
+    DP String_delta ();
657
+    void Compute_Energy ();
658
+    //void Compute_Momentum ();
659
+    void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
660
+
661
+    // XXX specific functions
662
+  public:
663
+    bool Check_Finite_rap ();
664
+
665
+  };
666
+
667
+  XXX_Bethe_State Add_Particle_at_Center (const XXX_Bethe_State& RefState);
668
+  XXX_Bethe_State Remove_Particle_at_Center (const XXX_Bethe_State& RefState);
669
+
670
+  //****************************************************************************
671
+
672
+  // Objects in class XXZ_gpd_Bethe_State carry all extra information pertaining to XXZ gapped antiferromagnets
673
+
674
+  class XXZ_gpd_Bethe_State : public Heis_Bethe_State {
675
+    
676
+  public:
677
+    Lambda sinlambda;  
678
+    Lambda coslambda;  
679
+    Lambda tanlambda;  
680
+
681
+  public:
682
+    XXZ_gpd_Bethe_State (); 
683
+    XXZ_gpd_Bethe_State (const XXZ_gpd_Bethe_State& RefState);  // copy constructor
684
+    XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, int M);  // constructor to ground-state configuration
685
+    XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& base);  // constructor to lowest-energy config with base
686
+    //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
687
+
688
+  public:
689
+    XXZ_gpd_Bethe_State& operator= (const XXZ_gpd_Bethe_State& RefState);
690
+
691
+  public:
692
+    void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
693
+    void Compute_sinlambda();
694
+    void Compute_coslambda();
695
+    void Compute_tanlambda();
696
+    int Weight();   // weight function for contributions cutoff 
697
+    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.
698
+    void Compute_BE (int j, int alpha);
699
+    void Compute_BE ();
700
+    DP Iterate_BAE(int i, int j);
701
+    void Iterate_BAE_Newton();
702
+    bool Check_Rapidities();  // checks that all rapidities are not nan and are in interval ]-PI/2, PI/2]
703
+    DP String_delta ();
704
+    void Compute_Energy ();
705
+    //void Compute_Momentum ();
706
+    void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
707
+
708
+    // XXZ_gpd specific functions
709
+  public:
710
+
711
+  };
712
+
713
+  XXZ_gpd_Bethe_State Add_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState);
714
+  XXZ_gpd_Bethe_State Remove_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState);
715
+
716
+  //***********************************************
717
+  
718
+  // Function declarations
719
+
720
+  // in M_vs_H.cc
721
+  DP Ezero (DP Delta, int N, int M);
722
+  DP H_vs_M (DP Delta, int N, int M);
723
+  DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref);
724
+  int M_vs_H (DP Delta, int N, DP HZ);
725
+
726
+  DP X_avg (char xyorz, DP Delta, int N, int M);
727
+
728
+  DP Chemical_Potential (const Heis_Bethe_State& RefState);
729
+  DP Particle_Hole_Excitation_Cost (char whichDSF, Heis_Bethe_State& AveragingState);
730
+
731
+  //DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& RefState, DP Chem_Pot, bool fixed_iK, int iKneeded);
732
+  DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
733
+  void Evaluate_F_Sumrule (string prefix, char whichDSF, const Heis_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
734
+
735
+  complex<DP> ln_Sz_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B);
736
+  complex<DP> ln_Smin_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B);
737
+
738
+  complex<DP> ln_Sz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
739
+  complex<DP> ln_Smin_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
740
+
741
+  // From Antoine Klauser:
742
+  complex<DP> ln_Szz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
743
+  complex<DP> ln_Szm_p_Smz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
744
+  complex<DP> ln_Smm_ME (XXX_Bethe_State& A, XXX_Bethe_State& B);
745
+
746
+  complex<DP> ln_Sz_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B);
747
+  complex<DP> ln_Smin_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B);
748
+
749
+  // The following functions have become member functions.
750
+  //DP String_delta (XXZ_Bethe_State& state);
751
+  //DP String_delta (XXX_Bethe_State& state);
752
+  //DP String_delta (XXZ_gpd_Bethe_State& state);
753
+
754
+  //DP Compute_Form_Factor_Entry (char whichDSF, Heis_Bethe_State& LeftState, Heis_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
755
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState, 
756
+  //				     XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
757
+  DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState, 
758
+				     XXZ_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
759
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState, 
760
+  //				     XXX_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
761
+  DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState, 
762
+				     XXX_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
763
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState, 
764
+  //				     XXZ_gpd_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
765
+  DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState, 
766
+				     XXZ_gpd_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
767
+
768
+  // For geometric quench:
769
+  complex<DP> ln_Overlap (XXX_Bethe_State& A, XXX_Bethe_State& B);
770
+
771
+  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, 
772
+				   int N_2, int iKmin, int iKmax, int Max_Secs, bool refine);
773
+
774
+
775
+} // namespace JSC
776
+
777
+#endif

+ 32
- 0
include/JSC_Infprec.h View File

@@ -0,0 +1,32 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_Infprec.h
10
+
11
+Purpose:  Declarations for infinite precision arithmetic classes.
12
+
13
+***********************************************************/
14
+
15
+
16
+#ifndef _JSC_INFPREC_
17
+#define _JSC_INFPREC_
18
+
19
+namespace JSC {
20
+
21
+  class infprec_int {
22
+    
23
+  private:
24
+    int nintrep; // number of integers used in representation
25
+    int baseint; // fundamental int
26
+    Vect<unsigned int> xint; // extra integers
27
+ 
28
+  }
29
+
30
+} // namespace JSC
31
+
32
+#endif

+ 331
- 0
include/JSC_Integ.h View File

@@ -0,0 +1,331 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_Integ.h
10
+
11
+Purpose:  Declares combinatorics-related classes and functions.
12
+
13
+
14
+***********************************************************/
15
+
16
+#ifndef _INTEG_
17
+#define _INTEG_
18
+
19
+#include "JSC.h"
20
+
21
+namespace JSC {
22
+
23
+
24
+  //**********************  Class Domain ************************
25
+
26
+  template<class T>
27
+    class Domain {
28
+    
29
+  private:
30
+    Vect<T> bdry;
31
+
32
+  public:
33
+    Domain () : bdry(Vect<T>(2))
34
+      {
35
+	bdry[0] = T(0);
36
+	bdry[1] = T(0);
37
+      }
38
+    
39
+  public:
40
+    Domain (T xmin_ref, T xmax_ref) : bdry(Vect<T>(2))
41
+      {
42
+	if (xmax_ref < xmin_ref) JSCerror("Use xmax > xmin in Domain.");
43
+	
44
+	bdry[0] = xmin_ref;
45
+	bdry[1] = xmax_ref;
46
+      }
47
+      
48
+  public:
49
+    inline T xmin (int i)
50
+      {
51
+	if (i > bdry.size()/2) JSCerror("i index too high in Domain::xmin.");
52
+	
53
+	return(bdry[2*i]);
54
+      }
55
+    
56
+  public:
57
+    inline T xmax (int i)
58
+      {
59
+	if (i > bdry.size()/2) JSCerror("i index too high in Domain::xmax.");
60
+	
61
+	return(bdry[2*i + 1]);
62
+      }
63
+    
64
+  public:
65
+    inline int Ndomains ()
66
+      {
67
+	return(bdry.size()/2);
68
+      }
69
+
70
+  public:
71
+    void Include (T xmin_ref, T xmax_ref) {
72
+      
73
+      // Determine the indices of xmin_ref & xmax_ref
74
+      int xmin_reg = -1;
75
+      int xmax_reg = -1;
76
+      for (int i = 0; i < bdry.size(); ++i) {
77
+	if ((i+1) % 2 && bdry[i] <= xmin_ref) xmin_reg++;
78
+	if (i % 2 && bdry[i] < xmin_ref) xmin_reg++;
79
+	if ((i+1) % 2 && bdry[i] <= xmax_ref) xmax_reg++;
80
+	if (i % 2 && bdry[i] < xmax_ref) xmax_reg++;
81
+      }
82
+      
83
+      //cout << "Include: xmin_reg = " << xmin_reg << "\txmax_reg = " << xmax_reg << endl;
84
+      
85
+      Vect<T> new_bdry(bdry.size() + 2 * ((xmin_reg % 2 && xmax_reg % 2) - (xmax_reg - xmin_reg)/2));
86
+      
87
+      int ishift = 0;
88
+      for (int i = 0; i <= xmin_reg; ++i) new_bdry[i] = bdry[i];
89
+      if (xmin_reg % 2) {
90
+	new_bdry[xmin_reg + 1] = xmin_ref; 
91
+	ishift++;
92
+	if (xmax_reg % 2) {
93
+	  new_bdry[xmin_reg + 2] = xmax_ref;
94
+	  ishift++;
95
+	}
96
+      }
97
+      else if ((xmin_reg + 1) % 2 && xmax_reg % 2) {
98
+	new_bdry[xmin_reg + 1] = xmax_ref;
99
+	ishift++;
100
+      }
101
+      for (int i = xmin_reg + ishift + 1; i < new_bdry.size(); ++i)
102
+	new_bdry[i] = bdry[xmax_reg - xmin_reg - ishift + i];
103
+      
104
+      bdry = new_bdry;
105
+      
106
+      return;
107
+    }
108
+    
109
+  public:
110
+    void Exclude (T xmin_ref, T xmax_ref) {
111
+      
112
+      // Determine the indices of xmin_ref & xmax_ref
113
+      int xmin_reg = -1;
114
+      int xmax_reg = -1;
115
+      for (int i = 0; i < bdry.size(); ++i) {
116
+	if ((i+1) % 2 && bdry[i] <= xmin_ref) xmin_reg++;
117
+	if (i % 2 && bdry[i] < xmin_ref) xmin_reg++;
118
+	if ((i+1) % 2 && bdry[i] <= xmax_ref) xmax_reg++;
119
+	if (i % 2 && bdry[i] < xmax_ref) xmax_reg++;
120
+      }
121
+      
122
+      //cout << "Exclude: xmin_reg = " << xmin_reg << "\txmax_reg = " << xmax_reg << endl;
123
+      
124
+      Vect<T> new_bdry(bdry.size() + 2 * (((xmin_reg + 1) % 2 && (xmax_reg + 1) % 2) - (xmax_reg - xmin_reg)/2));
125
+      
126
+      int ishift = 0;
127
+      for (int i = 0; i <= xmin_reg; ++i) new_bdry[i] = bdry[i];
128
+      if ((xmin_reg + 1) % 2) {
129
+	new_bdry[xmin_reg + 1] = xmin_ref; 
130
+	ishift++;
131
+	if ((xmax_reg + 1) % 2) {
132
+	  new_bdry[xmin_reg + 2] = xmax_ref;
133
+	  ishift++;
134
+	}
135
+      }
136
+      else if (xmin_reg % 2 && (xmax_reg + 1) % 2) {
137
+	new_bdry[xmin_reg + 1] = xmax_ref;
138
+	ishift++;
139
+      }
140
+      for (int i = xmin_reg + ishift + 1; i < new_bdry.size(); ++i)
141
+	new_bdry[i] = bdry[xmax_reg - xmin_reg - ishift + i];
142
+      
143
+      bdry = new_bdry;
144
+      
145
+      return;
146
+    }
147
+    
148
+  };
149
+
150
+  template<class T>
151
+    std::ostream& operator<< (std::ostream& s, Domain<T> dom)
152
+    {
153
+      for (int i = 0; i < dom.Ndomains(); ++i) {
154
+	if (i > 0) s << endl;
155
+	s << dom.xmin(i) << "\t" << dom.xmax(i);
156
+      }
157
+      return(s);
158
+    }
159
+
160
+  // ********************************* struct I_table ************************
161
+
162
+  struct I_table {
163
+
164
+    DP (*function) (DP, DP);
165
+    int Nvals;
166
+    DP rhomin;
167
+    DP rhomax;
168
+    DP alpha;
169
+    DP logalpha;
170
+    DP prec;
171
+    //Vect_DP rho_tbl;
172
+    //Vect_DP I_tbl;
173
+    DP* rho_tbl;
174
+    DP* I_tbl;
175
+    
176
+    I_table (DP (*function) (DP, DP), DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec);
177
+    DP Return_val (DP req_rho);
178
+    void Save ();
179
+    bool Load (DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec);
180
+
181
+  };
182
+
183
+
184
+  // ********************************* struct Integral_table ************************
185
+
186
+  struct Integral_table {
187
+
188
+    DP (*function) (DP, DP, int);
189
+    int Nvals;
190
+    DP rhomin;
191
+    DP rhomax;
192
+    DP alpha;
193
+    DP logalpha;
194
+    DP prec;
195
+    int maxnrpts;
196
+    DP* rho_tbl;
197
+    DP* I_tbl;
198
+    
199
+    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);
200
+    DP Return_val (DP req_rho);
201
+    void Save (const char* filenameprefix);
202
+    bool Load (const char* filenameprefix, DP rhomin_ref, DP rhomax_ref, int Nvals_ref, DP req_prec, int max_nr_pts);
203
+
204
+  };
205
+
206
+
207
+  // ******************************** Recursive integration functions ******************************
208
+
209
+  DP Integrate_Riemann (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, int Npts);
210
+  DP Integrate_Riemann_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, 
211
+				    DP xmin, DP xmax, int Npts);
212
+
213
+  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);
214
+  DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, 
215
+				DP xmin, DP xmax, DP req_prec, int max_rec_level);
216
+  DP Integrate_rec_using_table (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, 
217
+				DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile);
218
+  DP Integrate_rec_using_table_and_file (DP (*function) (Vect_DP, I_table, ofstream&), Vect_DP& args, int arg_to_integ, I_table Itable, 
219
+					 DP xmin, DP xmax, DP req_prec, int max_rec_level, ofstream& outfile);
220
+
221
+
222
+
223
+  // ******************************** Recursive version:  optimal ******************************
224
+
225
+  struct data_pt {
226
+    DP x;
227
+    DP f;
228
+    DP dx;
229
+  };
230
+
231
+  struct Integral_result {
232
+    DP integ_est;
233
+    DP abs_prec;
234
+    DP rel_prec;
235
+    int n_vals;
236
+  };
237
+
238
+  std::ostream& operator<< (std::ostream& s, const Integral_result& res);
239
+
240
+  class Integral_data {
241
+
242
+  private:
243
+    data_pt* data;  
244
+    DP* abs_d2f_dx;  // second derivative * dx
245
+    DP max_abs_d2f_dx;  // 
246
+
247
+  public:
248
+    //int n_vals;
249
+    Integral_result integ_res;
250
+
251
+  public:
252
+    DP xmin;
253
+    DP xmax;
254
+
255
+  public:
256
+    Integral_data (DP (*function_ref) (Vect_DP), Vect_DP& args, int arg_to_integ_ref, DP xmin_ref, DP xmax_ref);
257
+    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);
258
+    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);
259
+    void Save (ofstream& outfile);
260
+    void Improve_estimate (DP (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, int Npts_max);
261
+    void Improve_estimate (DP (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, int Npts_max);
262
+    void Improve_estimate (DP (*function) (Vect_DP, Integral_table), Vect_DP& args, int arg_to_integ, Integral_table Itable, int Npts_max);
263
+    ~Integral_data ();
264
+
265
+  };
266
+
267
+  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);
268
+  Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ, 
269
+						 I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
270
+  Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, Integral_table Itable), Vect_DP& args, int arg_to_integ, 
271
+						 Integral_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
272
+
273
+  Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ, 
274
+						 I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile);
275
+
276
+  // ******************************** Recursive version:  optimal, complex implementation ******************************
277
+
278
+  // NB:  function returns complex values but takes real arguments 
279
+
280
+  struct data_pt_CX {
281
+    DP x;
282
+    complex<DP> f;
283
+    DP dx;
284
+  };
285
+
286
+  struct Integral_result_CX {
287
+    complex<DP> integ_est;
288
+    DP abs_prec;
289
+    DP rel_prec;
290
+    int n_vals;
291
+  };
292
+
293
+  class Integral_data_CX {
294
+
295
+  private:
296
+    data_pt_CX* data;  
297
+    DP* abs_d2f_dx;  // second derivative * dx
298
+    DP max_abs_d2f_dx;  // 
299
+
300
+  public:
301
+    //int n_vals;
302
+    Integral_result_CX integ_res;
303
+
304
+  public:
305
+    DP xmin;
306
+    DP xmax;
307
+
308
+  public:
309
+    Integral_data_CX (complex<DP> (*function_ref) (Vect_DP), Vect_DP& args, int arg_to_integ_ref, DP xmin_ref, DP xmax_ref);
310
+    //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);
311
+    void Save (ofstream& outfile);
312
+    void Improve_estimate (complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, int Npts_max);
313
+    //void Improve_estimate (complex<DP> (*function) (Vect_DP, I_table), Vect_DP& args, int arg_to_integ, I_table Itable, int Npts_max);
314
+    ~Integral_data_CX ();
315
+
316
+  };
317
+
318
+  Integral_result_CX Integrate_optimal (complex<DP> (*function) (Vect_DP), Vect_DP& args, int arg_to_integ, DP xmin, DP xmax, 
319
+					DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
320
+  //Integral_result_CX Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ, 
321
+  //					 I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts);
322
+  //Integral_result Integrate_optimal_using_table (DP (*function) (Vect_DP, I_table Itable), Vect_DP& args, int arg_to_integ, 
323
+  //					 I_table Itable, DP xmin, DP xmax, DP req_rel_prec, DP req_abs_prec, int max_nr_pts, ofstream& outfile);
324
+
325
+
326
+
327
+
328
+
329
+} // namespace JSC
330
+
331
+#endif

+ 190
- 0
include/JSC_LiebLin.h View File

@@ -0,0 +1,190 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_LiebLin.h
10
+
11
+Purpose:  Declares LiebLin gas-related classes and functions.
12
+
13
+***********************************************************/
14
+
15
+#ifndef _LIEBLIN_
16
+#define _LIEBLIN_
17
+
18
+#include "JSC.h"
19
+
20
+namespace JSC {
21
+
22
+  // First, some global constants...
23
+
24
+  //const DP ITER_REQ_PREC_LIEBLIN = 1.0e+6 * MACHINE_EPS_SQ;
25
+  const DP ITER_REQ_PREC_LIEBLIN = 1.0e+4 * MACHINE_EPS_SQ;
26
+
27
+  const int LIEBLIN_Ix2_MIN = -1000000; // Like a UV cutoff. Assumption: never reached in scanning.
28
+  const int LIEBLIN_Ix2_MAX = -LIEBLIN_Ix2_MIN;
29
+
30
+  //***********************************************************************
31
+
32
+  //class LiebLin_Bethe_State : public Bethe_State {
33
+  class LiebLin_Bethe_State {
34
+
35
+  public:
36
+    DP c_int;  // interaction parameter
37
+    DP L;  
38
+    DP cxL;
39
+    int N;
40
+    string label;
41
+    //Vect<int> OriginStateIx2; // quantum numbers of state on which excitations are built; always ordered
42
+    Vect<int> Ix2_available; // quantum numbers which are allowable but not occupied
43
+    Vect<int> index_first_hole_to_right;
44
+    Vect<int> displacement;
45
+    Vect<int> Ix2;
46
+    Vect<DP> lambdaoc;
47
+    //Vect<DP> BE;
48
+    Vect<DP> S; // scattering sum
49
+    Vect<DP> dSdlambdaoc; // its derivative
50
+    DP diffsq;
51
+    DP prec;
52
+    int conv;
53
+    int iter_Newton;
54
+    DP E;
55
+    int iK;
56
+    DP K;
57
+    DP lnnorm;
58
+
59
+  public:
60
+    LiebLin_Bethe_State ();
61
+    LiebLin_Bethe_State (DP c_int_ref, DP L_ref, int N_ref);
62
+    LiebLin_Bethe_State& operator= (const LiebLin_Bethe_State& RefState);
63
+
64
+  public:
65
+    int Charge () { return(N); }; 
66
+    void Set_to_Label (string label_ref, const Vect<int>& OriginStateIx2);
67
+    void Set_to_Label (string label_ref); // assumes OriginState == GroundState
68
+    void Set_Label_from_Ix2 (const Vect<int>& OriginStateIx2);
69
+    void Set_Label_Internals_from_Ix2 (const Vect<int>& OriginStateIx2);
70
+    bool Check_Admissibility(char whichDSF); // always returns true
71
+    void Find_Rapidities (bool reset_rapidities);
72
+    bool Check_Rapidities();  // checks that all rapidities are not nan
73
+    DP String_delta(); // trivially returns 0; exists to mirror spin chain function
74
+    bool Check_Symmetry ();  // checks whether set of quantum numbers obeys { I } = { -I }
75
+    void Compute_lnnorm ();
76
+    void Compute_All (bool reset_rapidities);     // solves BAE, computes E, K and lnnorm
77
+    void Set_Free_lambdaocs();
78
+    void Iterate_BAE(DP damping);
79
+    void Iterate_BAE_S(DP damping);
80
+    void Iterate_BAE_Newton(DP damping);
81
+    void Compute_Energy ();
82
+    void Compute_Momentum ();
83
+    DP Kernel (int a, int b);
84
+    DP Kernel (DP lambdaoc_ref);
85
+    void Build_Reduced_Gaudin_Matrix (SQMat<DP>& Gaudin_Red);
86
+    void Build_Reduced_BEC_Quench_Gaudin_Matrix (SQMat<DP>& Gaudin_Red);
87
+    void Annihilate_ph_pair (int ipart, int ihole, const Vect<int>& OriginStateIx2);
88
+    void Parity_Flip ();  // takes all lambdaoc to -lambdaoc
89
+    inline bool Set_to_Inner_Skeleton (int iKneeded, const Vect<int>& OriginIx2)
90
+    {
91
+      if (N < 3) JSCerror("N<3 incompatible with fixed momentum scanning");
92
+      Ix2[0] = Ix2[1] - 2;
93
+      Ix2[N-1] = Ix2[N-2] + 2;
94
+      (*this).Compute_Momentum();
95
+      if (iKneeded >= iK) Ix2[N-1] += 2*(iKneeded - iK);
96
+      else Ix2[0] += 2*(iKneeded - iK);
97
+      if (Ix2[0] < LIEBLIN_Ix2_MIN || Ix2[N-1] > LIEBLIN_Ix2_MAX) return(false);
98
+      (*this).Set_Label_from_Ix2 (OriginIx2);
99
+      return(true);
100
+    }
101
+    void Set_to_Outer_Skeleton (const Vect<int>& OriginIx2) 
102
+    { 
103
+      Ix2[0] = LIEBLIN_Ix2_MIN + (N % 2) + 1; 
104
+      Ix2[N-1] = LIEBLIN_Ix2_MAX - (N % 2) - 1; 
105
+      (*this).Set_Label_from_Ix2 (OriginIx2);
106
+      //cout << "Set state to outer skeleton: Ix2 " << (*this).Ix2 << endl;
107
+      //cout << "label " << (*this).label << endl;
108
+    };
109
+  };
110
+
111
+  inline bool Is_Inner_Skeleton (LiebLin_Bethe_State& State) { 
112
+    return (State.N >= 2 && (State.Ix2[0] == State.Ix2[1] - 2 || State.Ix2[State.N-1] == State.Ix2[State.N-2] + 2)); 
113
+  }; 
114
+  inline bool Is_Outer_Skeleton (LiebLin_Bethe_State& State) { 
115
+    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); 
116
+  }; 
117
+  inline bool Is_Outer_Skeleton (const LiebLin_Bethe_State& State) { 
118
+    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); 
119
+  }; 
120
+
121
+  inline bool Force_Descent (char whichDSF, LiebLin_Bethe_State& ScanState, LiebLin_Bethe_State& RefState, int desc_type_required, int iKmod, DP Chem_Pot)
122
+  {
123
+    bool forcedesc = false;
124
+
125
+    // Force descent if we're computing density-density, we're at zero momentum and we're descending with momentum preserved:
126
+    if (whichDSF == 'd' && ScanState.iK == RefState.iK && desc_type_required > 8) forcedesc = true;
127
+
128
+    // For BEC to c > 0 quench, g2(x=0): force first step
129
+    else if (whichDSF == 'B' && ScanState.label == RefState.label) forcedesc = true;
130
+    else if (whichDSF == 'C' && ScanState.label == RefState.label) forcedesc = true;
131
+
132
+    return(forcedesc);
133
+  }
134
+
135
+  std::ostream& operator<< (std::ostream& s, const LiebLin_Bethe_State& state);
136
+
137
+  // FUNCTION DECLARATIONS:
138
+
139
+  DP Chemical_Potential (LiebLin_Bethe_State& RefState);
140
+  DP Sumrule_Factor (char whichDSF, LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
141
+  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);
142
+  void Evaluate_F_Sumrule (string prefix, char whichDSF, const LiebLin_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
143
+  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);
144
+
145
+  // in LiebLin_Utils.cc
146
+  DP LiebLin_dE0_dc (DP c_int, DP L, int N);
147
+  DP LiebLin_vs (DP c_int, DP L, int N);
148
+  DP LiebLin_Dressed_Charge_N (DP c_int, DP L, int N);
149
+  int Momentum_Right_Excitations (LiebLin_Bethe_State& ScanState);
150
+  int Momentum_Left_Excitations (LiebLin_Bethe_State& ScanState);
151
+  DP ln_Overlap_with_BEC (LiebLin_Bethe_State& lambda);
152
+
153
+  DP Particle_Hole_Excitation_Cost (char whichDSF, LiebLin_Bethe_State& AveragingState);
154
+
155
+  complex<DP> ln_Density_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate);
156
+  complex<DP> ln_Psi_ME (LiebLin_Bethe_State& lstate, LiebLin_Bethe_State& rstate);
157
+  complex<DP> ln_g2_ME (LiebLin_Bethe_State& mu, LiebLin_Bethe_State& lambda);
158
+
159
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState, 
160
+  //				     LiebLin_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
161
+  DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, LiebLin_Bethe_State& LeftState, 
162
+				     LiebLin_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
163
+
164
+  DP LiebLin_Twisted_lnnorm (Vect<complex<DP> >& lambdaoc, double cxL);
165
+  complex<DP> LiebLin_Twisted_ln_Overlap (DP expbeta, Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
166
+  complex<DP> LiebLin_Twisted_ln_Overlap (complex<DP> expbeta, Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
167
+  complex<DP> LiebLin_ln_Overlap (Vect<DP> lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
168
+  complex<DP> LiebLin_ln_Overlap (Vect<complex<DP> > lstate_lambdaoc, DP lstate_lnnorm, LiebLin_Bethe_State& rstate);
169
+
170
+  // In src/LiebLin_Tgt0.cc:
171
+  //DP Entropy_rho (LiebLin_Bethe_State& RefState, int Delta);
172
+  //DP Entropy_Fixed_Delta (LiebLin_Bethe_State& RefState, int Delta);
173
+  //DP Entropy (LiebLin_Bethe_State& RefState, int Delta);
174
+  DP Entropy (LiebLin_Bethe_State& RefState);
175
+  //DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, int Delta);
176
+  DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT);
177
+  //DP Entropy (LiebLin_Bethe_State& RefState, DP epsilon);
178
+  //DP Canonical_Free_Energy (LiebLin_Bethe_State& RefState, DP kBT, DP epsilon);
179
+  //LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, int Delta);
180
+  //LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT, DP epsilon);
181
+  LiebLin_Bethe_State Canonical_Saddle_Point_State (DP c_int, DP L, int N, DP kBT);
182
+  LiebLin_Bethe_State Add_Particle_at_Center (const LiebLin_Bethe_State& RefState);
183
+  LiebLin_Bethe_State Remove_Particle_at_Center (const LiebLin_Bethe_State& RefState);
184
+  DP rho_of_lambdaoc_1 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta);
185
+  DP rho_of_lambdaoc_2 (LiebLin_Bethe_State& RefState, DP lambdaoc, DP delta);
186
+
187
+
188
+} // namespace JSC
189
+
190
+#endif

+ 440
- 0
include/JSC_Matrix.h View File

@@ -0,0 +1,440 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_Matrix.h
10
+
11
+Purpose:  Declares square matrix class.
12
+
13
+***********************************************************/
14
+
15
+#ifndef _MATRIX_
16
+#define _MATRIX_
17
+
18
+namespace JSC {
19
+
20
+
21
+  // CLASS DEFINITIONS
22
+
23
+  template <class T> 
24
+    class SQMat {
25
+    
26
+  private:
27
+    int dim;
28
+    T** M;
29
+    
30
+  public:
31
+    SQMat (int N);             // initializes all elements of this n by n matrix to zero
32
+    SQMat (const SQMat& rhs);  // copy constructor
33
+    SQMat (const T& a, int N);  // initialize to diagonal matrix with value a (NOT like in NR !!!)
34
+    SQMat (const SQMat& a, const SQMat& b);  // initialize to tensor product of a and b
35
+    SQMat (const SQMat& a, int row_id, int col_id);  // init by cutting row row_id and col col_id
36
+    void Print ();
37
+    SQMat& operator= (const SQMat& rhs);  // assignment
38
+    SQMat& operator= (const T& a);        // assign 1 to diagonal elements (NOT like in NR !!!)
39
+    inline T* operator[] (const int i);  // subscripting: pointer to row i
40
+    inline const T* operator[] (const int i) const;
41
+    SQMat& operator+= (const T& a);
42
+    SQMat& operator+= (const SQMat& a);
43
+    SQMat& operator-= (const T& a);
44
+    SQMat& operator-= (const SQMat& a);
45
+    SQMat& operator*= (const T& a);
46
+    SQMat& operator*= (const SQMat& a);
47
+    inline int size() const;
48
+    ~SQMat();
49
+    
50
+  };
51
+  
52
+  template <class T>
53
+    SQMat<T>::SQMat (int N) : dim(N) , M(new T*[N])
54
+    {
55
+      M[0] = new T[N*N];
56
+      for (int i = 1; i < N; i++) M[i] = M[i-1] + N;
57
+    }
58
+    
59
+    template <class T>
60
+      SQMat<T>::SQMat (const SQMat& rhs) : dim(rhs.dim) , M(new T*[dim])
61
+      {
62
+	int i,j;
63
+	M[0] = new T[dim*dim];
64
+	for (i = 1; i < dim; i++) M[i] = M[i-1] + dim;
65
+	for (i = 0; i < dim; i++) 
66
+	  for (j = 0; j < dim; j++) M[i][j] = rhs[i][j];
67
+      }
68
+      
69
+      template <class T>
70
+	SQMat<T>::SQMat (const T& a, int N) : dim(N) , M(new T*[dim])
71
+	{
72
+	  int i, j;
73
+	  M[0] = new T[dim*dim];
74
+	  for (i = 1; i < dim; i++) M[i] = M[i-1] + dim;
75
+	  for (i = 0; i < dim; i++) {
76
+	    for (j = 0; j < dim; j++) M[i][j] = T(0); 
77
+	    M[i][i] = a;
78
+	  }
79
+	}
80
+	
81
+    template <class T>
82
+    SQMat<T>::SQMat (const SQMat& a, const SQMat& b) : dim (a.dim * b.dim) , M(new T*[a.dim * b.dim]) 
83
+    {
84
+      M[0] = new T[a.dim * b.dim * a.dim * b.dim];
85
+
86
+      for (int i = 1; i < a.dim * b.dim; ++i) M[i] = M[i-1] + a.dim * b.dim;
87
+    
88
+      for (int i1 = 0; i1 < a.dim; ++i1) {
89
+
90
+	for (int i2 = 0; i2 < a.dim; ++i2) {
91
+
92
+	  for (int j1 = 0; j1 < b.dim; ++j1) {
93
+
94
+	    for (int j2 = 0; j2 < b.dim; ++j2) {
95
+
96
+    	      M[i1 * (b.dim) + j1][i2 * (b.dim) + j2] = a[i1][i2] * b[j1][j2];
97
+	    }
98
+	  }
99
+	}
100
+      }
101
+    }
102
+
103
+      template <class T>
104
+	SQMat<T>::SQMat (const SQMat&a, int row_id, int col_id) : dim (a.dim - 1) , M(new T*[dim])
105
+	{
106
+	  if (dim == 0) {
107
+	    JSCerror("Error:  chopping a row and col from size one matrix.");
108
+	    exit(1);
109
+	  }
110
+    
111
+    	  M[0] = new T[dim * dim];
112
+
113
+	  for (int i = 1; i < dim; ++i) M[i] = M[i-1] + dim;
114
+
115
+	  for (int i = 0; i < row_id; ++i)
116
+	    for (int j = 0; j < col_id; ++j) M[i][j] = a[i][j];
117
+	  for (int i = row_id; i < dim; ++i)
118
+	    for (int j = 0; j < col_id; ++j) M[i][j] = a[i+1][j];
119
+	  for (int i = 0; i < row_id; ++i)
120
+	    for (int j = col_id; j < dim; ++j) M[i][j] = a[i][j+1];
121
+	  for (int i = row_id; i < dim; ++i)
122
+	    for (int j = col_id; j < dim; ++j) M[i][j] = a[i+1][j+1];
123
+	  
124
+	}
125
+
126
+  // operators
127
+	template <class T>
128
+	void SQMat<T>::Print ()
129
+	{
130
+	  cout << endl;
131
+	  for (int i = 0; i < dim; ++i) {
132
+	    for (int j = 0; j < dim; ++j) cout << M[i][j] << " ";
133
+	    cout << endl;
134
+	  }
135
+	  cout << endl;
136
+	}
137
+
138
+    template <class T>
139
+    SQMat<T>& SQMat<T>::operator= (const SQMat<T>& rhs)
140
+    {
141
+      if (this != &rhs) {
142
+	if (dim != rhs.dim) {
143
+	  JSCerror("Assignment between matrices of different dimensions.  Bailing out.");
144
+	  exit(1);
145
+	}
146
+
147
+	for (int i = 0; i < dim; ++i) 
148
+	  for (int j = 0; j < dim; ++j) M[i][j] = rhs[i][j];
149
+      }
150
+      return *this;
151
+    }
152
+
153
+    template <class T>
154
+    SQMat<T>& SQMat<T>::operator= (const T& a)
155
+    {
156
+      for (int i = 0; i < dim; ++i) {
157
+	for (int j = 0; j < dim; ++j) 
158
+	  M[i][j] = T(0);
159
+	M[i][i] = a;
160
+      }
161
+      return *this;
162
+    }
163
+
164
+    template <class T>
165
+    inline T* SQMat<T>::operator[] (const int i)
166
+    {
167
+      return M[i];
168
+    }
169
+
170
+    template <class T>
171
+    inline const T* SQMat<T>::operator[] (const int i) const
172
+    {
173
+      return M[i];
174
+    }
175
+
176
+    template <class T>
177
+      SQMat<T>& SQMat<T>::operator+= (const T& a)
178
+      {
179
+
180
+	for (int i = 0; i < dim; ++i) M[i][i] += a;
181
+
182
+	return *this;
183
+      }
184
+
185
+    template <class T>
186
+      SQMat<T>& SQMat<T>::operator+= (const SQMat<T>& a)
187
+      {
188
+	if (dim != a.dim) {
189
+	  JSCerror("Incompatible matrix sizes in matrix operator +.");
190
+	  exit(1);
191
+	}
192
+	for (int i = 0; i < dim; ++i) {
193
+	  for (int j = 0; j < dim; ++j) {
194
+	    M[i][j] += a[i][j];
195
+	  }
196
+	}
197
+	return *this;
198
+      }
199
+
200
+    template <class T>
201
+      SQMat<T>& SQMat<T>::operator-= (const T& a)
202
+      {
203
+
204
+	for (int i = 0; i < dim; ++i) M[i][i] -= a;
205
+
206
+	return *this;
207
+      }
208
+
209
+    template <class T>
210
+      SQMat<T>& SQMat<T>::operator-= (const SQMat<T>& a)
211
+      {
212
+	if (dim != a.dim) {
213
+	  JSCerror("Incompatible matrix sizes in matrix operator +.");
214
+	  exit(1);
215
+	}
216
+	for (int i = 0; i < dim; ++i) {
217
+	  for (int j = 0; j < dim; ++j) {
218
+	    M[i][j] -= a[i][j];
219
+	  }
220
+	}
221
+	return *this;
222
+      }
223
+
224
+    template <class T>
225
+      SQMat<T>& SQMat<T>::operator*= (const T& a)
226
+      {
227
+
228
+	for (int i = 0; i < dim; ++i) for (int j = 0; j < dim; ++j) M[i][j] *= a;
229
+
230
+	return *this;
231
+      }
232
+
233
+    template <class T>
234
+      SQMat<T>& SQMat<T>::operator*= (const SQMat<T>& a)
235
+      {
236
+
237
+	if (dim != a.dim) {
238
+	  JSCerror("Incompatible matrix sizes in matrix operator *.");
239
+	  exit(1);
240
+	}
241
+
242
+	SQMat<T> leftarg(*this);  // use copy constructor.
243
+    
244
+	for (int i = 0; i < dim; ++i) {
245
+
246
+	  for (int j = 0; j < dim; ++j) {
247
+
248
+	    M[i][j] = 0.0;
249
+
250
+	    for (int k = 0; k < dim; ++k) {
251
+
252
+	      M[i][j] += leftarg[i][k] * a[k][j];
253
+	    }
254
+	  }
255
+	}
256
+
257
+	return *this;
258
+      }
259
+  
260
+    template <class T>
261
+    inline int SQMat<T>::size() const
262
+    {
263
+      return dim;
264
+    }
265
+
266
+    template <class T>
267
+    SQMat<T>::~SQMat()
268
+    {
269
+      if (M != 0) {
270
+	delete[] (M[0]);
271
+	delete[] (M);
272
+      }
273
+    }
274
+
275
+
276
+    //*****************************
277
+
278
+  template <class T> 
279
+    class RecMat {
280
+    
281
+  private:
282
+    int nrows;
283
+    int ncols;
284
+    T** M;
285
+    
286
+  public:
287
+    RecMat (int Nrows, int Ncols);             // initializes all elements of this n by n matrix to zero
288
+    RecMat (const T& a, int Nrows, int Ncols);
289
+     RecMat (const RecMat& rhs);  // copy constructor
290
+    void Print ();
291
+    RecMat& operator= (const RecMat& rhs);  // assignment
292
+    inline T* operator[] (const int i);  // subscripting: pointer to row i
293
+    inline const T* operator[] (const int i) const;
294
+    inline int nr_rows() const;
295
+    inline int nr_cols() const;
296
+    ~RecMat();
297
+    
298
+  };
299
+  
300
+  template <class T>
301
+    RecMat<T>::RecMat (int Nrows, int Ncols) : nrows(Nrows), ncols(Ncols), M(new T*[Nrows])
302
+    {
303
+      M[0] = new T[Nrows*Ncols];
304
+      for (int i = 1; i < Nrows; i++) M[i] = M[i-1] + Ncols;
305
+
306
+      for (int i = 0; i < Nrows; i++) for (int j = 0; j < Ncols; j++) M[i][j] = T(0);
307
+    }
308
+
309
+  template <class T>
310
+    RecMat<T>::RecMat (const T& a, int Nrows, int Ncols) : nrows(Nrows), ncols(Ncols), M(new T*[Nrows])
311
+    {
312
+      M[0] = new T[Nrows*Ncols];
313
+      for (int i = 1; i < Nrows; i++) M[i] = M[i-1] + Ncols;
314
+
315
+      for (int i = 0; i < Nrows; i++) for (int j = 0; j < Ncols; j++) {
316
+	if (i == j) M[i][i] = a;
317
+	else M[i][j] = T(0);
318
+      }
319
+    }
320
+    
321
+    template <class T>
322
+      RecMat<T>::RecMat (const RecMat& rhs) : nrows(rhs.nrows), ncols(rhs.ncols), M(new T*[nrows])
323
+      {
324
+	int i,j;
325
+	M[0] = new T[nrows*ncols];
326
+	for (i = 1; i < nrows; i++) M[i] = M[i-1] + ncols;
327
+	for (i = 0; i < nrows; i++) 
328
+	  for (j = 0; j < ncols; j++) M[i][j] = rhs[i][j];
329
+      }
330
+      
331
+  // operators
332
+	template <class T>
333
+	void RecMat<T>::Print ()
334
+	{
335
+	  cout << endl;
336
+	  for (int i = 0; i < nrows; ++i) {
337
+	    for (int j = 0; j < ncols; ++j) cout << M[i][j] << " ";
338
+	    cout << endl;
339
+	  }
340
+	  cout << endl;
341
+	}
342
+
343
+    template <class T>
344
+    RecMat<T>& RecMat<T>::operator= (const RecMat<T>& rhs)
345
+    {
346
+      if (this != &rhs) {
347
+	if (nrows != rhs.nrows || ncols != rhs.ncols) {
348
+	  if (M != 0) {
349
+	    delete[] (M[0]);
350
+	    delete[] (M);
351
+	  }
352
+	  nrows = rhs.nrows;
353
+	  ncols = rhs.ncols;
354
+	  M = new T*[nrows];
355
+	  M[0] = new T[nrows * ncols];
356
+	}
357
+
358
+	for (int i = 0; i < nrows; ++i) 
359
+	  for (int j = 0; j < ncols; ++j) M[i][j] = rhs[i][j];
360
+      }
361
+      return *this;
362
+    }
363
+
364
+    template <class T>
365
+    inline T* RecMat<T>::operator[] (const int i)
366
+    {
367
+      return M[i];
368
+    }
369
+
370
+    template <class T>
371
+    inline const T* RecMat<T>::operator[] (const int i) const
372
+    {
373
+      return M[i];
374
+    }
375
+
376
+    template <class T>
377
+    inline int RecMat<T>::nr_rows() const
378
+    {
379
+      return nrows;
380
+    }
381
+
382
+    template <class T>
383
+    inline int RecMat<T>::nr_cols() const
384
+    {
385
+      return ncols;
386
+    }
387
+
388
+    template <class T>
389
+      inline std::ostream& operator<< (std::ostream& s, const RecMat<T>& matrix)
390
+      {
391
+	for (int i = 0; i < matrix.nr_rows(); ++i) {
392
+	  for (int j = 0; j < matrix.nr_cols(); ++j) s << matrix[i][j] << " ";
393
+	  s << endl;
394
+	}
395
+
396
+	return (s);
397
+      }
398
+
399
+    template <class T>
400
+    RecMat<T>::~RecMat()
401
+    {
402
+      if (M != 0) {
403
+	delete[] (M[0]);
404
+	delete[] (M);
405
+      }
406
+    }
407
+
408
+    // TYPEDEFS:
409
+
410
+    typedef JSC::SQMat<DP> SQMat_DP;
411
+    typedef JSC::SQMat<complex<double> > SQMat_CX;
412
+
413
+
414
+    // FUNCTION DEFINITIONS
415
+
416
+    // Functions in src/MATRIX directory
417
+
418
+    DP det_LU (SQMat_DP a);
419
+    DP lndet_LU (SQMat_DP a);
420
+    complex<DP> lndet_LU_dstry (SQMat_DP& a);
421
+    complex<DP> det_LU_CX (SQMat_CX a);
422
+    complex<DP> lndet_LU_CX (SQMat_CX a);
423
+    complex<DP> lndet_LU_CX_dstry (SQMat_CX& a);
424
+    void eigsrt (Vect_DP& d, SQMat_DP& v);
425
+    void balanc (SQMat_DP& a);
426
+    void elmhes (SQMat_DP& a);
427
+    void gaussj (SQMat_DP& a, SQMat_DP& b);
428
+    void hqr (SQMat_DP& a, Vect_CX& wri);
429
+    void jacobi (SQMat_DP& a, Vect_DP& d, SQMat_DP& v, int& nrot);
430
+    void lubksb (SQMat_DP& a, Vect_INT& indx, Vect_DP& b);
431
+    void lubksb_CX (SQMat_CX& a, Vect_INT& indx, Vect_CX& b);
432
+    void ludcmp (SQMat_DP& a, Vect_INT& indx, DP& d);  
433
+    void ludcmp_CX (SQMat_CX& a, Vect_INT& indx, DP& d);  
434
+    DP pythag(DP a, DP b);
435
+    void tqli(Vect_DP& d, Vect_DP& e, SQMat_DP& z);
436
+    void tred2 (SQMat_DP& a, Vect_DP& d, Vect_DP& e);
437
+        
438
+} // namespace JSC
439
+
440
+#endif

+ 36
- 0
include/JSC_NRG.h View File

@@ -0,0 +1,36 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_NRG.h
10
+
11
+Purpose:  Declares NRG-related classes and functions.
12
+
13
+***********************************************************/
14
+
15
+#ifndef _NRG_
16
+#define _NRG_
17
+
18
+#include "JSC.h"
19
+
20
+namespace JSC {
21
+
22
+  DP K_Weight_integrand (Vect_DP args);  // weighing function for state selection
23
+
24
+  //void Select_States_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required, bool symmetric_states, int iKmod,
25
+  //		      int weighing_option, DP (*weight_integrand_fn) (Vect_DP), Vect_DP& args_to_weight_integrand);
26
+  void Select_States_for_NRG (DP c_int, DP L, int N, int iKmin, int iKmax, int Nstates_required, bool symmetric_states, int iKmod,
27
+			      //int weighing_option, DP (*weight_integrand_fn) (Vect_DP), Vect_DP& args_to_weight_integrand)
28
+			      int weighing_option, Vect<complex <DP> >& FT_of_potential);
29
+  
30
+  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, 
31
+				       int weighing_option, int label_left_begin, int label_left_end, int label_right_begin, int label_right_end,
32
+				       int block_option, DP* DFF_block_1, DP* DFF_block_2, Vect_DP Kweight);
33
+
34
+}
35
+
36
+#endif // _NRG_

+ 463
- 0
include/JSC_ODSLF.h View File

@@ -0,0 +1,463 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Heis.h
10
+
11
+Purpose:  Declares lattice spinless fermion classes and functions.
12
+
13
+***********************************************************/
14
+
15
+#ifndef _ODSLF_
16
+#define _ODSLF_
17
+
18
+#include "JSC.h"
19
+
20
+namespace JSC {
21
+
22
+  //****************************************************************************
23
+
24
+  // Objects in class ODSLF_Base are a checked vector containing the number of rapidities of allowable types for a given state
25
+
26
+  class ODSLF_Base {
27
+
28
+  public:
29
+    int Mdown;         // total number of down spins
30
+    Vect<int> Nrap;    // Nrap[i] contains the number of rapidities of type i, i = 0, Nstrings - 1.
31
+    int Nraptot;       // total number of strings in this state
32
+    Vect<DP> Ix2_infty;  // Ix2_infty[i] contains the max of BAE function for the (half-)integer I[i], i = 0, Nstrings - 1.
33
+    Vect<int> Ix2_max;    // Ix2_max[i] contains the integer part of 2*I_infty, with correct parity for base.
34
+    long long int id;  // identification number
35
+
36
+  public:
37
+    ODSLF_Base ();
38
+    ODSLF_Base (const ODSLF_Base& RefBase);  // copy constructor
39
+    ODSLF_Base (const Heis_Chain& RefChain, int M);  // constructs configuration with all Mdown in one-string of +1 parity
40
+    ODSLF_Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities);  // sets to Nrapidities vector, and checks consistency
41
+    ODSLF_Base (const Heis_Chain& RefChain, long long int id_ref);
42
+    inline int& operator[] (const int i);
43
+    inline const int& operator[] (const int i) const; 
44
+    ODSLF_Base& operator= (const ODSLF_Base& RefBase);
45
+    bool operator== (const ODSLF_Base& RefBase);
46
+    bool operator!= (const ODSLF_Base& RefBase);
47
+
48
+    void Compute_Ix2_limits(const Heis_Chain& RefChain);  // computes the Ix2_infty and Ix2_max 
49
+
50
+    void Scan_for_Possible_Types (Vect<long long int>& possible_type_id, int& nfound, int base_level, Vect<int>& Nexcitations);
51
+    Vect<long long int> Possible_Types ();  // returns a vector of possible types
52
+
53
+  };
54
+
55
+  inline int& ODSLF_Base::operator[] (const int i)
56
+  {
57
+    return Nrap[i];
58
+  }
59
+  
60
+  inline const int& ODSLF_Base::operator[] (const int i) const
61
+  {
62
+    return Nrap[i];
63
+  }
64
+
65
+  //****************************************************************************
66
+
67
+  // Objects in class ODSLF_Ix2_Config carry all the I's of a given state
68
+
69
+  class ODSLF_Ix2_Config {
70
+
71
+    //private:
72
+  public:
73
+    int Nstrings;
74
+    Vect<int> Nrap;
75
+    int Nraptot;
76
+
77
+    int** Ix2;
78
+
79
+    //Vect<Vect<int> > Ix2;
80
+
81
+  public:
82
+    ODSLF_Ix2_Config ();
83
+    ODSLF_Ix2_Config (const Heis_Chain& RefChain, int M);   // constructor, puts I's to ground state
84
+    ODSLF_Ix2_Config (const Heis_Chain& RefChain, const ODSLF_Base& base);   // constructor, putting I's to lowest-energy config 
85
+                                                               // consistent with Heis_Base configuration for chain RefChain
86
+    ODSLF_Ix2_Config& operator= (const ODSLF_Ix2_Config& RefConfig);
87
+    inline int* operator[] (const int i);
88
+    //inline Vect<int> operator[] (const int i);
89
+    inline const int* operator[] (const int i) const;
90
+    //inline const Vect<int> operator[] (const int i) const;
91
+    ~ODSLF_Ix2_Config();
92
+  };
93
+
94
+  inline int* ODSLF_Ix2_Config::operator[] (const int i)
95
+  //inline Vect<int> Ix2_Config::operator[] (const int i)
96
+    {
97
+      return Ix2[i];
98
+    }
99
+  
100
+  inline const int* ODSLF_Ix2_Config::operator[] (const int i) const
101
+  //inline const Vect<int> Ix2_Config::operator[] (const int i) const
102
+  {
103
+    return Ix2[i];
104
+  }
105
+
106
+  std::ostream& operator<< (std::ostream& s, const ODSLF_Ix2_Config& RefConfig);
107
+
108
+  //****************************************************************************
109
+
110
+  // Objects in class ODSLF_Lambda carry all rapidities of a state
111
+
112
+  class ODSLF_Lambda {
113
+    
114
+  private:
115
+    int Nstrings;
116
+    Vect<int> Nrap;
117
+    int Nraptot;
118
+    DP** lambda;
119
+    //Vect<Vect<DP> > lambda;
120
+    
121
+  public:
122
+    ODSLF_Lambda ();
123
+    ODSLF_Lambda (const Heis_Chain& RefChain, int M);   // constructor, puts all lambda's to zero
124
+    ODSLF_Lambda (const Heis_Chain& RefChain, const ODSLF_Base& base);   // constructor, putting I's to lowest-energy config 
125
+    // consistent with Heis_Base configuration for chain RefChain
126
+    ODSLF_Lambda& operator= (const ODSLF_Lambda& RefConfig);
127
+    inline DP* operator[] (const int i);
128
+    //inline Vect<DP> operator[] (const int i);
129
+    inline const DP* operator[] (const int i) const;
130
+    //inline const Vect<DP> operator[] (const int i) const;
131
+    ~ODSLF_Lambda();
132
+
133
+  };
134
+
135
+  inline DP* ODSLF_Lambda::operator[] (const int i)
136
+  //inline Vect<DP> Lambda::operator[] (const int i)
137
+    {
138
+      return lambda[i];
139
+    }
140
+  
141
+  inline const DP* ODSLF_Lambda::operator[] (const int i) const
142
+  //inline const Vect<DP> Lambda::operator[] (const int i) const
143
+    {
144
+      return lambda[i];
145
+    }
146
+
147
+
148
+  //****************************************************************************
149
+
150
+  // Objects in class ODSLF_Ix2_Offsets carry Young tableau representations of the Ix2 configurations
151
+
152
+  class ODSLF_Ix2_Offsets {
153
+
154
+  public:
155
+    ODSLF_Base base;
156
+    Vect<Young_Tableau> Tableau;  // vector of pointers to tableaux at each level
157
+    long long int type_id;
158
+    long long int id;        // id number of offset
159
+    long long int maxid;     // max id number allowable
160
+
161
+  public:
162
+    ODSLF_Ix2_Offsets ();
163
+    ODSLF_Ix2_Offsets (const ODSLF_Ix2_Offsets& RefOffset);  // copy constructor
164
+    ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, long long int req_type_id);
165
+    ODSLF_Ix2_Offsets (const ODSLF_Base& RefBase, Vect<int> nparticles);  // sets all tableaux to empty ones, with nparticles[] at each level
166
+    ODSLF_Ix2_Offsets& operator= (const ODSLF_Ix2_Offsets& RefOffset);
167
+    bool operator<= (const ODSLF_Ix2_Offsets& RefOffsets);
168
+    bool operator>= (const ODSLF_Ix2_Offsets& RefOffsets);
169
+
170
+  public:
171
+    void Set_to_id (long long int idnr);  
172
+    void Compute_id ();
173
+    void Compute_type_id ();
174
+
175
+  public:
176
+    bool Add_Boxes_From_Lowest (int Nboxes, bool odd_sectors); // adds Nboxes in minimal energy config, all boxes in either even or odd sectors
177
+
178
+  };
179
+
180
+  inline long long int ODSLF_Ix2_Offsets_type_id (Vect<int>& nparticles)
181
+    {
182
+      long long int type_id_here = 0ULL;
183
+
184
+      for (int i = 0; i < nparticles.size(); ++i)
185
+	type_id_here += nparticles[i] * pow_ulli(10ULL, i);
186
+
187
+      return(type_id_here);
188
+    }
189
+
190
+  //****************************************************************************
191
+  // Objects in class ODSLF_Ix2_Offsets_List carry a vector of used Ix2_Offsets
192
+
193
+  class ODSLF_Ix2_Offsets_List {
194
+
195
+  public:
196
+    int ndef;
197
+    Vect<ODSLF_Ix2_Offsets> Offsets;
198
+
199
+  public:
200
+    ODSLF_Ix2_Offsets_List ();
201
+    ODSLF_Ix2_Offsets& Return_Offsets (ODSLF_Base& RefBase, Vect<int> nparticles);  // returns the Ix2_Offsets corresponding to nparticles[]/base
202
+    ODSLF_Ix2_Offsets& Return_Offsets (ODSLF_Base& RefBase, long long int req_type_id);
203
+  };
204
+
205
+
206
+  //****************************************************************************
207
+
208
+  // Objects in class ODSLF_Bethe_State carry all information about an eigenstate
209
+
210
+  // Derived classes include XXZ_Bethe_State, XXX_Bethe_State, XXZ_gpd_Bethe_State
211
+  // These contain subclass-specific functions and data.
212
+
213
+  class ODSLF_Bethe_State {
214
+    
215
+  public:
216
+    Heis_Chain chain;
217
+    ODSLF_Base base;
218
+    ODSLF_Ix2_Offsets offsets;
219
+    ODSLF_Ix2_Config Ix2;
220
+    ODSLF_Lambda lambda;
221
+    ODSLF_Lambda BE;            // Bethe equation for relevant rapidity, in the form BE = theta - (1/N)\sum ... - \pi I/N = 0
222
+    DP diffsq;             // sum of squares of rapidity differences in last iteration 
223
+    int conv;              // convergence status
224
+    int iter;              // number of iterations necessary for convergence
225
+    int iter_Newton;              // number of iterations necessary for convergence (Newton method)
226
+    DP E;                  // total energy
227
+    int iK;                // K = 2.0*PI * iK/Nsites
228
+    DP K;                  // total momentum
229
+    DP lnnorm;             // ln of norm of reduced Gaudin matrix
230
+    //long long int id;
231
+    //long long int maxid;
232
+    long long int base_id;
233
+    long long int type_id;
234
+    long long int id;
235
+    long long int maxid;
236
+    int nparticles;
237
+
238
+  public:
239
+    ODSLF_Bethe_State (); 
240
+    ODSLF_Bethe_State (const ODSLF_Bethe_State& RefState);  // copy constructor
241
+    ODSLF_Bethe_State (const ODSLF_Bethe_State& RefState, long long int type_id_ref);  // new state with requested type_id
242
+    ODSLF_Bethe_State (const Heis_Chain& RefChain, int M);  // constructor to ground-state configuration
243
+    ODSLF_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& base);  // constructor to lowest-energy config with base
244
+    ODSLF_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref);  
245
+    virtual ~ODSLF_Bethe_State () {};
246
+
247
+  public:
248
+    int Charge () { return(base.Mdown); }; 
249
+    //void Set_I_Offset (const I_Offset& RefOffset);  // sets the Ix2 to given offsets
250
+    void Set_Ix2_Offsets (const ODSLF_Ix2_Offsets& RefOffset);  // sets the Ix2 to given offsets
251
+    void Set_to_id (long long int id_ref);
252
+    void Set_to_id (long long int id_ref, ODSLF_Bethe_State& RefState);
253
+    int Nparticles (); // counts the number of particles in state once Ix2 offsets set (so type_id is correctly set)
254
+    bool Check_Symmetry ();  // checks whether the I's are symmetrically distributed
255
+    void Compute_diffsq ();  // \sum BE[j][alpha]^2
256
+    void Iterate_BAE ();     // Finds new set of lambda[j][alpha] from previous one by simple iteration
257
+    void Iterate_BAE_Newton ();     // Finds new set of lambda[j][alpha] from previous one by a Newton step
258
+    void Find_Rapidities (bool reset_rapidities);  // Finds the rapidities
259
+    void Find_Rapidities_Twisted (bool reset_rapidities, DP twist);  // Finds the rapidities with twist added to RHS of logBE
260
+    void BAE_smackdown (DP max_allowed);
261
+    void Solve_BAE_smackdown (DP max_allowed, int maxruns);
262
+    void Solve_BAE (int j, int alpha, DP req_prec, int itermax);
263
+    void Solve_BAE_interp (DP interp_prec, int max_iter_interp);
264
+    void Solve_BAE_straight_iter (DP interp_prec, int max_iter_interp);
265
+    void Solve_BAE_Newton (DP Newton_prec, int max_iter_Newton);
266
+    void Compute_lnnorm ();
267
+    void Compute_Momentum ();
268
+    void Compute_All (bool reset_rapidities);     // solves BAE, computes E, K and lnnorm
269
+    bool Boost_Momentum (int iKboost);
270
+
271
+    // Virtual functions, all defined in the derived classes
272
+
273
+  public:
274
+    virtual void Set_Free_lambdas() { JSCerror("ODSLF_Bethe_State::..."); }  // sets the rapidities to solutions of BAEs without scattering terms
275
+    virtual bool Check_Admissibility(char option) { JSCerror("ODSLF_Bethe_State::..."); return(false); }   
276
+    // verifies that we don't have a symmetrical Ix2 config with a Ix2 == 0 for a string of even length >= 2.
277
+    virtual void Compute_BE (int j, int alpha) { JSCerror("ODSLF_Bethe_State::..."); }
278
+    virtual void Compute_BE () { JSCerror("ODSLF_Bethe_State::..."); }
279
+    virtual DP Iterate_BAE(int i, int alpha) { JSCerror("ODSLF_Bethe_State::..."); return(0.0);}
280
+    virtual bool Check_Rapidities() { JSCerror("ODSLF_Bethe_State::..."); return(false); }
281
+    virtual void Compute_Energy () { JSCerror("ODSLF_Bethe_State::..."); }
282
+    virtual void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red) { JSCerror("ODSLF_Bethe_State::..."); }
283
+  };
284
+
285
+  inline bool Force_Descent (char whichDSF, ODSLF_Bethe_State& ScanState, ODSLF_Bethe_State& RefState, int desc_type_required, int iKmod, DP Chem_Pot)
286
+  {
287
+    JSCerror("Need to implement Force_Descent properly for ODSLF.");
288
+
289
+    bool force_descent = false;
290
+
291
+    // Force descent if energy of ScanState is lower than that of RefState
292
+    if (ScanState.E - RefState.E - (ScanState.base.Mdown - RefState.base.Mdown) < 0.0) return(true); 
293
+    /*
294
+    // We force descent if 
295
+    // 1)  - there exists a higher string whose quantum number is still on 0
296
+    // AND - there is at most a single particle-hole in the 0 base level
297
+    // AND - either the particle or the hole hasn't yet moved.
298
+    if (RefState.base_id/100000LL > 0) { // there is a higher string
299
+      int type0 = RefState.type_id % 10000;
300
+      if (type0 == 0 
301
+	  || type0 == 101 && RefState.offsets.Tableau[0].id * RefState.offsets.Tableau[2].id == 0LL 
302
+	  || type0 == 110 && RefState.offsets.Tableau[1].id * RefState.offsets.Tableau[2].id == 0LL 
303
+	  || type0 == 1001 && RefState.offsets.Tableau[0].id * RefState.offsets.Tableau[3].id == 0LL 
304
+	  || type0 == 1010 && RefState.offsets.Tableau[1].id * RefState.offsets.Tableau[3].id == 0LL) // single p-h pair in base level 0
305
+	for (int j = 1; j < RefState.chain.Nstrings; ++j) {
306
+	  if (RefState.base[j] == 1 && RefState.Ix2[j][0] == 0) {
307
+	    force_descent = true;
308
+	  }
309
+	}
310
+    }
311
+    */
312
+    // Force descent if quantum nr distribution is symmetric:
313
+    if (RefState.Check_Symmetry()) force_descent = true;
314
+    
315
+    return(force_descent);
316
+  }
317
+
318
+  std::ostream& operator<< (std::ostream& s, const ODSLF_Bethe_State& state);
319
+
320
+  //****************************************************************************
321
+
322
+  // Objects in class XXZ_Bethe_State carry all extra information pertaining to XXZ gapless
323
+
324
+  class ODSLF_XXZ_Bethe_State : public ODSLF_Bethe_State {
325
+    
326
+  public:
327
+    ODSLF_Lambda sinhlambda;  
328
+    ODSLF_Lambda coshlambda;  
329
+    ODSLF_Lambda tanhlambda;  
330
+
331
+  public:
332
+    ODSLF_XXZ_Bethe_State (); 
333
+    ODSLF_XXZ_Bethe_State (const ODSLF_XXZ_Bethe_State& RefState);  // copy constructor
334
+    ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, int M);  // constructor to ground-state configuration
335
+    ODSLF_XXZ_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& base);  // constructor to lowest-energy config with base
336
+    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
337
+
338
+  public:
339
+    ODSLF_XXZ_Bethe_State& operator= (const ODSLF_XXZ_Bethe_State& RefState);
340
+    
341
+  public:
342
+    void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
343
+    void Compute_sinhlambda();
344
+    void Compute_coshlambda();
345
+    void Compute_tanhlambda();
346
+    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.
347
+    void Compute_BE (int j, int alpha);
348
+    void Compute_BE ();
349
+    DP Iterate_BAE(int i, int j);
350
+    bool Check_Rapidities();  // checks that all rapidities are not nan
351
+    void Compute_Energy ();
352
+    //void Compute_Momentum ();
353
+    void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);    
354
+
355
+    // XXZ specific functions:
356
+  public:
357
+
358
+  };
359
+
360
+  //****************************************************************************
361
+  /*
362
+  // Objects in class ODSLF_XXX_Bethe_State carry all extra information pertaining to XXX antiferromagnet
363
+
364
+  class ODSLF_XXX_Bethe_State : public ODSLF_Bethe_State {
365
+
366
+  public:
367
+    ODSLF_XXX_Bethe_State (); 
368
+    ODSLF_XXX_Bethe_State (const ODSLF_XXX_Bethe_State& RefState);  // copy constructor
369
+    ODSLF_XXX_Bethe_State (const Heis_Chain& RefChain, int M);  // constructor to ground-state configuration
370
+    ODSLF_XXX_Bethe_State (const Heis_Chain& RefChain, const ODSLF__Base& base);  // constructor to lowest-energy config with base
371
+    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
372
+
373
+  public:
374
+    ODSLF_XXX_Bethe_State& operator= (const ODSLF_XXX_Bethe_State& RefState);
375
+
376
+  public:
377
+    void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
378
+    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.
379
+    void Compute_BE (int j, int alpha);
380
+    void Compute_BE ();
381
+    DP Iterate_BAE(int i, int j);
382
+    bool Check_Rapidities();  // checks that all rapidities are not nan    
383
+    void Compute_Energy ();
384
+    //void Compute_Momentum ();
385
+    void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
386
+
387
+    // XXX specific functions
388
+  public:
389
+    bool Check_Finite_rap ();
390
+
391
+  };
392
+  */
393
+  //****************************************************************************
394
+  /*
395
+  // Objects in class ODSLF_XXZ_gpd_Bethe_State carry all extra information pertaining to XXZ gapped antiferromagnets
396
+
397
+  class ODSLF_XXZ_gpd_Bethe_State : public ODSLF__Bethe_State {
398
+    
399
+  public:
400
+    Lambda sinlambda;  
401
+    Lambda coslambda;  
402
+    Lambda tanlambda;  
403
+
404
+  public:
405
+    ODSLF_XXZ_gpd_Bethe_State (); 
406
+    ODSLF_XXZ_gpd_Bethe_State (const ODSLF_XXZ_gpd_Bethe_State& RefState);  // copy constructor
407
+    ODSLF_XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, int M);  // constructor to ground-state configuration
408
+    ODSLF_XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, const ODSLF_Base& base);  // constructor to lowest-energy config with base
409
+    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
410
+
411
+  public:
412
+    ODSLF_XXZ_gpd_Bethe_State& operator= (const ODSLF_XXZ_gpd_Bethe_State& RefState);
413
+
414
+  public:
415
+    void Set_Free_lambdas(); // sets the rapidities to solutions of BAEs without scattering terms
416
+    void Compute_sinlambda();
417
+    void Compute_coslambda();
418
+    void Compute_tanlambda();
419
+    int Weight();   // weight function for contributions cutoff 
420
+    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.
421
+    void Compute_BE (int j, int alpha);
422
+    void Compute_BE ();
423
+    DP Iterate_BAE(int i, int j);
424
+    void Iterate_BAE_Newton();
425
+    bool Check_Rapidities();  // checks that all rapidities are not nan and are in interval ]-PI/2, PI/2]
426
+    void Compute_Energy ();
427
+    //void Compute_Momentum ();
428
+    void Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red);
429
+
430
+    // XXZ_gpd specific functions
431
+  public:
432
+
433
+  };
434
+  */
435
+  //***********************************************
436
+  
437
+  // Function declarations
438
+  /*
439
+  // in M_vs_H.cc
440
+  DP Ezero (DP Delta, int N, int M);
441
+  DP H_vs_M (DP Delta, int N, int M);
442
+  DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref);
443
+  int M_vs_H (DP Delta, int N, DP HZ);
444
+
445
+  DP X_avg (char xyorz, DP Delta, int N, int M);
446
+  */
447
+  DP Chemical_Potential (const ODSLF_Bethe_State& RefState);
448
+  //DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& RefState, DP Chem_Pot, bool fixed_iK, int iKneeded);
449
+  DP Sumrule_Factor (char whichDSF, ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
450
+  void Evaluate_F_Sumrule (string prefix, char whichDSF, const ODSLF_Bethe_State& RefState, DP Chem_Pot, int iKmin, int iKmax);
451
+
452
+  complex<DP> ln_Sz_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B);
453
+  complex<DP> ln_Smin_ME (ODSLF_XXZ_Bethe_State& A, ODSLF_XXZ_Bethe_State& B);
454
+
455
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, ODSLF_XXZ_Bethe_State& LeftState, 
456
+  //				     ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, fstream& DAT_outfile);
457
+  DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, ODSLF_XXZ_Bethe_State& LeftState, 
458
+				     ODSLF_XXZ_Bethe_State& RefState, DP Chem_Pot, stringstream& DAT_outfile);
459
+
460
+
461
+} // namespace JSC
462
+
463
+#endif

+ 1263
- 0
include/JSC_Scan.h
File diff suppressed because it is too large
View File


+ 207
- 0
include/JSC_Spec_Fns.h View File

@@ -0,0 +1,207 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_Spec_Fns.h
10
+
11
+Purpose:  Defines special math functions.
12
+
13
+***********************************************************/
14
+
15
+#ifndef _JSC_SPEC_FNS_H_
16
+#define _JSC_SPEC_FNS_H_
17
+
18
+#include "JSC.h"
19
+
20
+using namespace std;
21
+
22
+namespace JSC {
23
+
24
+  inline DP Cosine_Integral (DP x)
25
+  {
26
+
27
+    // Returns the Cosine integral -\int_x^\infty dt \frac{\cos t}{t}
28
+    // Refer to GR[6] 8.23
29
+
30
+    if (x <= 0.0) {
31
+      cout << "Cosine_Integral called with real argument " << x << " <= 0, which is ill-defined because of the branch cut." << endl;
32
+      JSCerror("");
33
+    }
34
+
35
+    else if (x < 15.0) { // Use power series expansion
36
+
37
+      // Ci (x) = gamma + \ln x + \sum_{n=1}^\infty (-1)^n x^{2n}/(2n (2n)!).
38
+
39
+      int n = 1;
40
+      DP minonetothen = -1.0;
41
+      DP logxtothetwon = 2.0 * log(x);
42
+      DP twologx = 2.0 * log(x);
43
+      DP logtwonfact = log(2.0);
44
+
45
+      DP series = minonetothen * exp(logxtothetwon - log(2.0 * n) - logtwonfact);
46
+      DP term_n;
47
+
48
+      do { 
49
+	n += 1;
50
+	minonetothen *= -1.0;
51
+	logxtothetwon += twologx;
52
+	logtwonfact += log((2.0 * n - 1.0) * 2.0 * n);
53
+	term_n = minonetothen * exp(logxtothetwon - log(2.0 * n) - logtwonfact);
54
+	series += term_n;
55
+
56
+      } while (fabs(term_n) > 1.0e-16);
57
+
58
+
59
+
60
+
61
+      /*
62
+      // For improved convergence we pair terms up,         DOESN'T WORK WELL
63
+
64
+      // 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)} )
65
+
66
+      int n = 1;
67
+      DP logxtothetwon = 2.0 * log(x);
68
+      DP logtwon = log(2.0);
69
+      DP logtwonfact = log(2.0);
70
+      DP xsq = x*x;
71
+
72
+      DP series = exp(logxtothetwon - logtwon - logtwonfact) * (1 - xsq/((2.0 * n + 1.0) * (2.0 * n + 2.0) * (1.0 + 1.0/n)));
73
+      DP term_n;
74
+      DP twologx = 2.0 * log(x);
75
+
76
+      do { 
77
+	n += 2;
78
+	logxtothetwon += twologx;
79
+	logtwonfact += log((2.0 * n - 1.0) * 2.0 * n);
80
+	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)));;
81
+	series += term_n;
82
+
83
+      } while (fabs(term_n) > 1.0e-16);
84
+      */
85
+
86
+      return(Euler_Mascheroni + log(x) + series);
87
+    }
88
+
89
+
90
+    else { // Use high x power series
91
+
92
+      // 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}
93
+
94
+      int n = 0;
95
+      DP minonetothen = 1.0;
96
+      DP logxtothetwon = 0.0;
97
+      DP logxtothetwonplus1 = log(x);
98
+      DP twologx = 2.0 * log(x);
99
+      DP logtwonfact = 0.0;
100
+      DP logtwonplus1fact = 0.0;
101
+
102
+      DP series1 = minonetothen * exp(logtwonfact - logxtothetwon);
103
+      DP series2 = minonetothen * exp(logtwonplus1fact - logxtothetwonplus1);
104
+
105
+      do { 
106
+	n += 1;
107
+	minonetothen *= -1.0;
108
+	logxtothetwon += twologx;
109
+	logxtothetwonplus1 += twologx;
110
+	logtwonfact += log((2.0 * n - 1.0) * 2.0 * n);
111
+	logtwonplus1fact += log(2.0 * n  * (2.0 * n + 1));
112
+
113
+	series1 += minonetothen * exp(logtwonfact - logxtothetwon);
114
+	series2 += minonetothen * exp(logtwonplus1fact - logxtothetwonplus1);
115
+
116
+      } while (n < 12);
117
+
118
+      return((sin(x)/x) * series1 - (cos(x)/x) * series2);
119
+
120
+    }
121
+
122
+
123
+    return(log(-1.0));
124
+  }
125
+
126
+
127
+  /*********** Jacobi Theta functions *********/
128
+
129
+  inline DP Jacobi_Theta_1_q (DP u, DP q) {
130
+
131
+    // Uses the summation formula.
132
+    // theta_1 (x) = 2 \sum_{n=1}^\infty (-1)^{n+1} q^{(n-1/2)^2} \sin (2n-1)u
133
+    // in which q is the nome. (GR 8.180.1)
134
+    // We always evaluate to numerical accuracy.
135
+
136
+    if (q >= 1.0) JSCerror("Jacobi_Theta_1_q function called with q > 1.");
137
+
138
+
139
+    DP answer = 0.0;
140
+    DP contrib = 0.0; 
141
+    DP qtonminhalfsq = pow(q, 0.25);  // this will be q^{(n-1/2)^2}
142
+    DP qtotwon = pow(q, 2.0); // this will be q^{2n}
143
+    DP qsq = q*q;
144
+    int n = 1;
145
+
146
+    do {
147
+      contrib = (n % 2 ? 2.0 : -2.0) * qtonminhalfsq * sin((2.0*n - 1.0)*u);
148
+      answer += contrib;
149
+      qtonminhalfsq *= qtotwon;
150
+      qtotwon *= qsq;
151
+      n++;
152
+      //cout << "\t\tn = " << n << "\tanswer = " << answer << "\tcontrib = " << contrib << "\tqtonminhalfsq = " << qtonminhalfsq << "\tqtotwon = " << qtotwon << endl;
153
+    } while (fabs(contrib/answer) > MACHINE_EPS);
154
+
155
+    //cout << "\t\tJacobi_Theta_1: used " << n << " iterations." << "\tanswer = " << answer << "\tcontrib = " << contrib << "\tqtonminhalfsq = " << qtonminhalfsq << "\tqtotwon = " << qtotwon << endl;
156
+    return(answer);
157
+  }
158
+
159
+  inline complex<DP> ln_Jacobi_Theta_1_q (complex<DP> u, complex<DP> q) {
160
+
161
+    // This uses the product representation
162
+    // \theta_1 (x) = 2 q^{1/4} \sin{u} \prod_{n=1}^\infty (1 - 2 q^{2n} \cos 2u + q^{4n}) (1 - q^{2n})
163
+    // (GR 8.181.2)
164
+
165
+    complex<DP> contrib = 0.0;
166
+    complex<DP> qtotwon = q*q; // this will be q^{2n}
167
+    complex<DP> qsq = q*q;
168
+    complex<DP> twocos2u = 2.0 * cos(2.0*u);
169
+    int n = 1;
170
+    complex<DP> answer = log(2.0 * sin(u)) + 0.25 * log(q);
171
+    
172
+    do {
173
+      contrib = log((1.0 - twocos2u * qtotwon + qtotwon * qtotwon) * (1.0 - qtotwon));
174
+      answer += contrib;
175
+      qtotwon *= qsq;
176
+      n++;
177
+    } while (abs(contrib) > 1.0e-12);
178
+
179
+    return(answer);
180
+  }
181
+
182
+
183
+  /************  Barnes function ************/
184
+
185
+  inline DP ln_Gamma_for_Barnes_G_RE (Vect_DP args)
186
+  {
187
+    return(real(ln_Gamma(complex<double>(args[0]))));
188
+  }
189
+
190
+  inline DP ln_Barnes_G_RE (DP z)
191
+  {
192
+    //  Implementation according to equation (28) of 2004_Adamchik_CPC_157
193
+    //  Restricted to real arguments.
194
+
195
+    Vect_DP args (0.0, 2);
196
+
197
+    DP req_rel_prec = 1.0e-6;
198
+    DP req_abs_prec = 1.0e-6;
199
+    int max_nr_pts = 10000;
200
+    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);
201
+
202
+    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);
203
+  }
204
+
205
+} // namespace JSC
206
+
207
+#endif // _JS_SPEC_FNS_H_

+ 47
- 0
include/JSC_State_Ensemble.h View File

@@ -0,0 +1,47 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_State_Ensemble.h
10
+
11
+Purpose:  Define state ensembles.
12
+
13
+
14
+***********************************************************/
15
+
16
+#ifndef _ENS_
17
+#define _ENS_
18
+
19
+#include "JSC.h"
20
+
21
+namespace JSC {
22
+
23
+
24
+  struct LiebLin_Diagonal_State_Ensemble {
25
+
26
+    int nstates;
27
+    Vect<LiebLin_Bethe_State> state;
28
+    Vect<DP> weight;
29
+
30
+    LiebLin_Diagonal_State_Ensemble ();
31
+    LiebLin_Diagonal_State_Ensemble (const LiebLin_Bethe_State& RefState, int nstates_req);
32
+    //LiebLin_Diagonal_State_Ensemble (const LiebLin_Bethe_State& RefState, int nstates_req, const Vect<DP>& weight_ref);
33
+    //LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho, int nstates_req);
34
+    LiebLin_Diagonal_State_Ensemble (DP c_int, DP L, int N, const Root_Density& rho);
35
+
36
+    LiebLin_Diagonal_State_Ensemble& operator= (const LiebLin_Diagonal_State_Ensemble& rhs);
37
+    void Load (DP c_int, DP L, int N, const char* ensfile_Cstr);
38
+    void Save (const char* ensfile_Cstr);
39
+  };
40
+
41
+  //LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT, int nstates_req);
42
+  LiebLin_Diagonal_State_Ensemble LiebLin_Thermal_Saddle_Point_Ensemble (DP c_int, DP L, int N, DP kBT);
43
+
44
+
45
+} // namespace JSC
46
+
47
+#endif

+ 147
- 0
include/JSC_TBA.h View File

@@ -0,0 +1,147 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS. library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_TBA.h
10
+
11
+Purpose:  Thermodynamic Bethe Ansatz general functions
12
+
13
+
14
+***********************************************************/
15
+
16
+#ifndef _TBA_
17
+#define _TBA_
18
+
19
+#include "JSC.h"
20
+
21
+namespace JSC {
22
+
23
+  struct Root_Density {
24
+    
25
+    int Npts;  // how many points are used to describe each function
26
+    DP lambdamax;  // what the largest rapidity is
27
+    Vect_DP lambda;  // rapidity vector
28
+    Vect_DP dlambda; // differential element
29
+    Vect_DP value;  // the root density itself
30
+    Vect_DP prev_value;  // results of previous iteration
31
+    DP diff;   // relative differences with previous iteration
32
+    bool value_infty_set;  // boolean, true if asymptotic value set
33
+    DP value_infty;  // asymptotic value, computed analytically
34
+    
35
+    Root_Density ();
36
+    Root_Density (int Npts_ref, DP lambdamax_ref);
37
+    
38
+    Root_Density& operator= (const Root_Density& RefDensity);
39
+    
40
+    void Save (const char* outfile_Cstr);
41
+
42
+    DP Return_Value (DP lambda_ref);  // evaluates the function for any argument using linear interpolation
43
+    void Set_Asymptotics (DP value_infty_ref);  // sets value for lambda >= lambdamax
44
+    
45
+    Root_Density Compress_and_Match_Densities (DP comp_factor);  // returns a Root_Density with fewer points
46
+  };
47
+
48
+  struct Root_Density_Set {
49
+    
50
+    int ntypes;
51
+    Vect<Root_Density> epsilon;
52
+    int Npts_total;  // sum of all Npts of epsilon's
53
+    DP diff;  // sum of diff's of the epsilon's
54
+    
55
+    Root_Density_Set ();
56
+    Root_Density_Set (int ntypes_ref, int Npts_ref, DP lambdamax_ref);
57
+    Root_Density_Set (int ntypes_ref, Vect_INT Npts_ref, Vect_DP lambdamax_ref);
58
+    
59
+    Root_Density_Set& operator= (const Root_Density_Set& RefSet);
60
+    
61
+    void Insert_new_function (DP asymptotic_value);
62
+    void Extend_limits (Vect<bool> need_to_extend_limit);
63
+    void Insert_new_points (Vect<Vect<bool> > need_new_point_around);
64
+    
65
+    DP Return_Value (int n_ref, DP lambda_ref);  // returns a value, no matter what.
66
+    
67
+    Root_Density_Set Return_Compressed_and_Matched_Set (DP comp_factor);
68
+    void Match_Densities (Root_Density_Set& RefSet);
69
+    
70
+    void Save (const char* outfile_Cstr);
71
+  };
72
+
73
+
74
+  struct LiebLin_TBA_Solution {
75
+
76
+    DP c_int;
77
+    DP mu;
78
+    DP kBT;
79
+    DP nbar;
80
+    DP ebar; // mean energy, \int d\lambda \lambda^2 \rho (\lambda)
81
+    DP sbar; // entropy per unit length
82
+    Root_Density epsilon;
83
+    Root_Density depsilon_dmu;
84
+    Root_Density rho;
85
+    Root_Density rhoh;
86
+
87
+    LiebLin_TBA_Solution (DP c_int_ref, DP mu_ref, DP kBT_ref, DP req_diff, int Max_Secs);
88
+  };
89
+
90
+  // Functions defined in TBA_LiebLin.cc
91
+  Root_Density LiebLin_rho_GS (DP c_int, DP k_F, DP lambdamax, int Npts, DP req_prec);
92
+  DP Density_GS (Root_Density& rho_GS);
93
+  DP k_F_given_n (DP c_int, DP n, DP lambdamax, int Npts, DP req_prec);
94
+  Root_Density LiebLin_Z_GS (DP c_int, DP k_F, DP lambdamax, int Npts, DP req_prec);
95
+  Root_Density LiebLin_Fbackflow_GS (DP c_int, DP k_F, DP lambdamax, DP lambda, int Npts, DP req_prec);
96
+  // epsilon for a given mu:
97
+  Root_Density LiebLin_epsilon_TBA (DP c_int, DP mu, DP kBT, DP req_diff, int Max_Secs);
98
+  // depsilon/dmu for a given mu:
99
+  Root_Density LiebLin_depsilon_dmu_TBA (DP c_int, DP mu, DP kBT, DP req_diff, int Max_Secs, const Root_Density& epsilon);
100
+  Root_Density LiebLin_rho_TBA (DP kBT, const Root_Density& epsilon, const Root_Density& depsilon_dmu);
101
+  Root_Density LiebLin_rhoh_TBA (DP kBT, const Root_Density& epsilon, const Root_Density& depsilon_dmu);
102
+  DP LiebLin_nbar_TBA (const Root_Density& rho);
103
+  DP LiebLin_ebar_TBA (const Root_Density& rho); 
104
+  DP LiebLin_sbar_TBA (const Root_Density& rho, const Root_Density& rhoh); 
105
+  LiebLin_TBA_Solution LiebLin_TBA_Solution_fixed_nbar (DP c_int, DP nbar_required, DP kBT, DP req_diff, int Max_Secs);
106
+  LiebLin_TBA_Solution LiebLin_TBA_Solution_fixed_nbar_ebar (DP c_int, DP nbar_required, DP ebar_required, DP req_diff, int Max_Secs);
107
+  LiebLin_Bethe_State Discretized_LiebLin_Bethe_State (DP c_int, DP L, int N, const Root_Density& rho);
108
+
109
+  // Functions defined in TBA_XXZ.cc 
110
+  DP XXZ_phi1_kernel (DP zeta, DP lambda);
111
+  DP XXZ_phi2_kernel (DP zeta, DP lambda);
112
+  DP XXZ_a1_kernel (DP sinzeta, DP coszeta, DP lambda);
113
+  DP XXZ_da1dlambda_kernel (DP sinzeta, DP coszeta, DP lambda);
114
+  DP XXZ_a2_kernel (DP sin2zeta, DP cos2zeta, DP lambda);
115
+  Root_Density XXZ_rhotot_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
116
+  DP Return_GS_Sz_tot_value (DP B, Root_Density& rhotot_GS);
117
+  Root_Density XXZ_eps_GS (DP Delta, DP Hz, DP lambdamax, int Npts, DP req_prec);
118
+  Root_Density XXZ_depsdlambda_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
119
+  Root_Density XXZ_b2BB_lambda_B (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
120
+  Root_Density XXZ_b2BB_lambda_lambdap (DP Delta, DP B, DP lambdap, DP lambdamax, int Npts, DP req_prec);
121
+  Root_Density XXZ_Kbackflow_GS (DP Delta, DP B, DP lambdamax, DP lambda_p, DP lambda_h, int Npts, DP req_prec);
122
+  Root_Density XXZ_Fbackflow_GS (DP Delta, DP B, DP lambdamax, DP lambda_p, DP lambda_h, int Npts, DP req_prec);
123
+  Root_Density XXZ_Z_GS (DP Delta, DP B, DP lambdamax, int Npts, DP req_prec);
124
+  //void XXZ_Compare_Lattice_and_Continuum_Backflows_base_1010 (DP Delta, int N, int M, long long int id);
125
+
126
+  // Defined in TBA_2CBG.cc:
127
+  struct TBA_Data_2CBG {
128
+    DP c_int;
129
+    DP mu;
130
+    DP Omega;
131
+    DP kBT;
132
+    DP f;  // Gibbs free energy
133
+    DP n1;  // first population
134
+    DP n2;  // second population
135
+  };
136
+
137
+  // Defined in src/TBA_2CBG.cc:
138
+  TBA_Data_2CBG Solve_2CBG_TBAE_via_refinements (DP c_int, DP mu, DP Omega, DP kBT, int Max_Secs, bool Save_data);
139
+
140
+  // Defined in src/TBA_2CBG.cc:
141
+  void Scan_2CBG_TBAE (DP c_int, DP mu_min, DP mu_max, int Nmu, DP Omega_min, DP Omega_max, int NOmega,
142
+		       DP kBT_min, DP kBT_max, int NkBT, int Max_Secs);
143
+
144
+  
145
+} // namespace JSC
146
+
147
+#endif

+ 472
- 0
include/JSC_Vect.h View File

@@ -0,0 +1,472 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_Vect.h
10
+
11
+Purpose:  Declares vector class.
12
+
13
+***********************************************************/
14
+
15
+#ifndef _JSC_VECT_
16
+#define _JSC_VECT_
17
+
18
+namespace JSC {
19
+
20
+  template <class T>
21
+    class Vect {
22
+  private:
23
+    int dim;
24
+    T* V;
25
+  public:
26
+    Vect();
27
+    explicit Vect (int N);
28
+    Vect (const T& a, int N);  // initialize all N elements are a
29
+    Vect (const T* a, int N);  // initialize to array
30
+    Vect (const Vect& rhs);   // Copy constructor
31
+    Vect& operator= (const Vect& rhs);  // assignment
32
+    Vect& operator= (const T& a);      // assign a to all elements
33
+    inline T& operator[] (const int i);
34
+    inline const T& operator[] (const int i) const;
35
+    Vect& operator+= (const Vect& rhs);  
36
+    Vect& operator-= (const Vect& rhs);
37
+    bool operator== (const Vect& rhs);  // checks equality of size and of all elements
38
+    bool operator!= (const Vect& rhs);  // checks inequality
39
+    bool Append (const T& rhs);  // appends rhs to the vector
40
+    bool Append (const Vect& rhs);  // appends rhs to the vector
41
+    bool Increase_Size (int nr_to_add); // resizes the array to accommodate nr_to_add more entries
42
+    bool Increase_Size (int nr_to_add, T setval); // resizes the array to accommodate nr_to_add more entries
43
+    inline int size() const;
44
+    inline double norm() const;  // returns norm of vector
45
+    inline T max() const;        // returns maximal value
46
+    inline T min() const;        // returns maximal value
47
+    inline T sum() const;        // returns sum of all elements
48
+    inline bool includes(T check) const;  // whether check == one of the elements or not
49
+    void QuickSort (int l, int r);
50
+    void QuickSort (Vect<int>& index, int l, int r);
51
+    void QuickSort ();
52
+    void QuickSort (Vect<int>& index);
53
+    ~Vect();
54
+  };
55
+  
56
+  template <class T>
57
+    Vect<T>::Vect() : dim(0), V(0) {}
58
+  
59
+  template <class T>
60
+    Vect<T>::Vect (int N) : dim(N), V(new T[N]) {}
61
+  
62
+  template <class T>
63
+    Vect<T>::Vect (const T& a, int N) : dim(N), V(new T[N])
64
+  {
65
+    for (int i = 0; i < N; ++i) V[i] = a;
66
+  }
67
+  
68
+  template <class T>
69
+    Vect<T>::Vect (const T* a, int N) : dim(N), V(new T[N])
70
+  {
71
+    for (int i = 0; i < N; ++i) V[i] = *a++;
72
+  }
73
+  
74
+  template <class T>
75
+    Vect<T>::Vect (const Vect<T>& rhs) : dim(rhs.dim), V(new T[dim])
76
+  {
77
+    for (int i = 0; i < dim; ++i) V[i] = rhs[i];
78
+  }
79
+  
80
+  template <class T>
81
+    Vect<T>& Vect<T>::operator= (const Vect<T>& rhs)
82
+    {
83
+      if (this != &rhs) {
84
+	if (dim != rhs.dim) {
85
+	  if (V != 0) delete[] V;
86
+	  dim = rhs.dim;
87
+	  V = new T[dim];
88
+	}
89
+	for (int i = 0; i < dim; ++i) V[i] = rhs[i];
90
+      }
91
+      return *this;
92
+    }
93
+  
94
+  template <class T>
95
+    Vect<T>& Vect<T>::operator= (const T& a)
96
+    {
97
+      for (int i = 0; i < dim; ++i) V[i] = a;
98
+      return *this;
99
+    }
100
+
101
+  template <class T>
102
+    inline T& Vect<T>::operator[] (const int i)
103
+  {
104
+    return V[i];
105
+  }
106
+  
107
+  template <class T>
108
+    inline const T& Vect<T>::operator[] (const int i) const
109
+  {
110
+    return V[i];
111
+  }
112
+
113
+  template <class T>
114
+    Vect<T>& Vect<T>::operator+= (const Vect<T>& rhs)
115
+    {
116
+      for (int i = 0; i < dim; ++i) V[i] += rhs[i];
117
+      return *this;
118
+    }
119
+  
120
+  template <class T>
121
+    Vect<T>& Vect<T>::operator-= (const Vect<T>& rhs)
122
+    {
123
+      for (int i = 0; i < dim; ++i) V[i] -= rhs[i];
124
+      return *this;
125
+    }
126
+
127
+  template <class T>
128
+    bool Vect<T>::operator== (const Vect<T>& rhs)
129
+    {
130
+      bool answer = ((*this).size() == rhs.size());
131
+      if (answer) {
132
+	for (int i = 0; i < dim; ++i) answer = (answer && (V[i] == rhs[i]));
133
+      }
134
+      return answer;
135
+    }
136
+
137
+  template <class T>
138
+    bool Vect<T>::operator!= (const Vect<T>& rhs)
139
+    {
140
+      return(!((*this) == rhs));
141
+    } 
142
+
143
+  template <class T>
144
+    bool Vect<T>::Append (const Vect<T>& rhs)  // appends rhs to the vector
145
+    {
146
+      T* newvect = new T[dim + rhs.size()];
147
+      for (int i = 0; i < dim; ++i) newvect[i] = V[i];
148
+      for (int i = 0; i < rhs.size(); ++i) newvect[i+ dim] = rhs[i];
149
+
150
+      dim += rhs.size();
151
+      delete[] V;
152
+      V = new T[dim];
153
+      for (int i = 0; i < dim; ++i) V[i] = newvect[i];
154
+
155
+      delete[] newvect;
156
+
157
+      return(true);
158
+    }
159
+
160
+  template <class T>
161
+    bool Vect<T>::Append (const T& rhs)  // appends rhs to the vector
162
+    {
163
+      T* newvect = new T[dim + 1];
164
+      for (int i = 0; i < dim; ++i) newvect[i] = V[i];
165
+      newvect[dim] = rhs;
166
+
167
+      dim += 1;
168
+      delete[] V;
169
+      V = new T[dim];
170
+      for (int i = 0; i < dim; ++i) V[i] = newvect[i];
171
+
172
+      delete[] newvect;
173
+
174
+      return(true);
175
+    }
176
+
177
+  template <class T>
178
+    bool Vect<T>::Increase_Size (int nr_to_add) // resizes the array to accommodate nr_to_add more entries
179
+    {
180
+      int resized_dim = dim + nr_to_add;
181
+
182
+      T* resized_vect = new T[resized_dim];
183
+      for (int i = 0; i < dim; ++i) resized_vect[i] = V[i];      
184
+      for (int i = dim; i < resized_dim; ++i) resized_vect[i] = T(0);
185
+
186
+      dim = resized_dim;
187
+      delete[] V;
188
+      V = new T[dim];
189
+      for (int i = 0; i < dim; ++i) V[i] = resized_vect[i];
190
+
191
+      delete[] resized_vect;
192
+
193
+      return(true);
194
+    }
195
+
196
+  template <class T>
197
+    bool Vect<T>::Increase_Size (int nr_to_add, T setval) // resizes the array to accommodate nr_to_add more entries
198
+    {
199
+      int resized_dim = dim + nr_to_add;
200
+
201
+      T* resized_vect = new T[resized_dim];
202
+      for (int i = 0; i < dim; ++i) resized_vect[i] = V[i];      
203
+      for (int i = dim; i < resized_dim; ++i) resized_vect[i] = setval;
204
+
205
+      dim = resized_dim;
206
+      delete[] V;
207
+      V = new T[dim];
208
+      for (int i = 0; i < dim; ++i) V[i] = resized_vect[i];
209
+
210
+      delete[] resized_vect;
211
+
212
+      return(true);
213
+    }
214
+
215
+
216
+  template <class T>
217
+    inline int Vect<T>::size() const
218
+  {
219
+    return dim;
220
+  }
221
+
222
+  template <class T>
223
+  inline double Vect<T>::norm () const
224
+    {
225
+      double normsq = 0.0;
226
+      for (int i = 0; i < dim; ++i) normsq += abs(V[i]) * abs(V[i]);
227
+      return sqrt(normsq);
228
+    }
229
+
230
+  template <>
231
+  inline double Vect<double>::norm () const
232
+    {
233
+      double normsq = 0.0;
234
+      for (int i = 0; i < dim; ++i) normsq += V[i] * V[i];
235
+      return(sqrt(normsq));
236
+    }
237
+
238
+  template <>
239
+  inline double Vect<complex<double> >::norm () const
240
+    {
241
+      double normsq = 0.0;
242
+      for (int i = 0; i < dim; ++i) normsq += std::norm(V[i]);
243
+      return(sqrt(normsq));
244
+    }
245
+
246
+  template <class T>
247
+    inline T Vect<T>::max() const
248
+    {
249
+      T maxval = V[0];
250
+      for (int i = 0; i < dim; ++i) if (V[i] > maxval) maxval = V[i];
251
+      return maxval;
252
+    }
253
+
254
+  template <class T>
255
+    inline T Vect<T>::min() const
256
+    {
257
+      T minval = V[0];
258
+      for (int i = 0; i < dim; ++i) if (V[i] < minval) minval = V[i];
259
+      return minval;
260
+    }
261
+
262
+  template <class T>
263
+    inline T Vect<T>::sum() const
264
+    {
265
+      T total = T(0);  
266
+      for (int i = 0; i < dim; ++i) total += V[i];
267
+      return total;
268
+    }
269
+
270
+  template <class T>
271
+    inline bool Vect<T>::includes (T check) const
272
+    {
273
+      int index = 0;
274
+      while (index < dim && V[index] != check) index++;
275
+
276
+      return(index < dim);
277
+    }
278
+  /*  
279
+  template <class T>
280
+    void Vect<T>::QuickSort (int l, int r)
281
+    {
282
+      //cout << "QuickSort called for l = " << l << "\t r = " << r << endl;
283
+      //cout << (*this) << endl;
284
+      //for (int ih = l; ih <= r; ++ih) cout << setprecision(16) << "ih = " << ih << "\tV[ih] = " << V[ih] << endl;
285
+
286
+      static T m;
287
+      static int j;
288
+      int i;
289
+
290
+      if (r > l) {
291
+	m = V[r]; i = l-1; j = r;
292
+
293
+	for (;;) {
294
+	  while (V[++i] < m);
295
+	  while (V[--j] > m);
296
+	  if (i >= j) break;
297
+	  std::swap(V[i], V[j]);
298
+	}
299
+	std::swap(V[i], V[r]);
300
+
301
+	(*this).QuickSort(l, i-1);
302
+	(*this).QuickSort(i+1, r);
303
+      }
304
+    }
305
+  */
306
+  /*
307
+  template <class T>
308
+    void Vect<T>::QuickSort (int l, int r)
309
+    {
310
+      // My own version of QuickSort: add sentinels on left and right
311
+      if (r > l) {
312
+	int s = l + (r-l)/2; // central element index
313
+	// Rearrange so that V[l] <= V[s] <= V[r] (sentinels on left and right)
314
+	if (V[l] > V[r]) std::swap(V[l],V[r]);
315
+	if (V[s] > V[r]) std::swap(V[s],V[r]);
316
+	if (V[l] > V[s]) std::swap(V[l],V[s]);
317
+	m = V[s]; i = l-1; j = r;
318
+	//m = V[r]; i = l-1; j = r;
319
+
320
+	for (;;) {
321
+	  while (V[i] < m) i++;
322
+	  while (V[j] > m) j--;
323
+	  if (i >= j) break;
324
+	  std::swap(V[i], V[j]); // restart from indices i and j just used, in case one is pivot
325
+	}
326
+	//std::swap(V[i], V[r]);
327
+
328
+	(*this).QuickSort(l, i-1);
329
+	(*this).QuickSort(i+1, r);
330
+      }
331
+
332
+    }
333
+  */
334
+
335
+  template <class T>
336
+    void Vect<T>::QuickSort (int l, int r)
337
+    {
338
+      int i = l, j = r;
339
+      T pivot = V[l + (r-l)/2];
340
+      
341
+      while (i <= j) {
342
+	while (V[i] < pivot) i++;
343
+	while (V[j] > pivot) j--;
344
+	if (i <= j) {
345
+	  std::swap(V[i],V[j]);
346
+	  i++;
347
+	  j--;
348
+	}
349
+      };
350
+      
351
+      if (l < j) (*this).QuickSort(l, j);
352
+      if (i < r) (*this).QuickSort(i, r);
353
+    }
354
+
355
+  template <class T>
356
+    void Vect<T>::QuickSort ()
357
+    {
358
+      if ((*this).size() > 1) (*this).QuickSort (0, (*this).size() - 1);
359
+    }
360
+
361
+  /*
362
+  template <class T>
363
+    void Vect<T>::QuickSort (Vect<int>& index, int l, int r)
364
+    {
365
+      if (index.size() != (*this).size()) {
366
+	cout << (*this).size() << "\t" << index.size() << endl;
367
+	JSCerror("Wrong dim for index in Vect QuickSort.");
368
+      }
369
+
370
+      static T m;
371
+      static int j;
372
+      int i;
373
+
374
+      if (r > l) {
375
+	m = V[r]; i = l-1; j = r;
376
+
377
+	for (;;) {
378
+	  while (V[++i] < m);
379
+	  while (V[--j] > m);
380
+	  if (i >= j) break;
381
+	  std::swap(V[i], V[j]);
382
+	  std::swap(index[i], index[j]);
383
+	}
384
+	std::swap(V[i], V[r]);
385
+	std::swap(index[i], index[r]);
386
+
387
+	(*this).QuickSort(index, l, i-1);
388
+	(*this).QuickSort(index, i+1, r);
389
+      }
390
+    }
391
+  */
392
+  /*
393
+  template <class T>
394
+    void Vect<T>::QuickSort (Vect<int>& index, int l, int r)
395
+    {
396
+      // My own version of QuickSort:
397
+      if (r > l) {
398
+	int s = l + (r-l)/2; // central element index
399
+	// Rearrange so that V[l] <= V[s] <= V[r] (sentinels on left and right)
400
+	if (V[l] > V[r]) std::swap(V[l],V[r]);
401
+	if (V[s] > V[r]) std::swap(V[s],V[r]);
402
+	if (V[l] > V[s]) std::swap(V[l],V[s]);
403
+	m = V[s]; i = l-1; j = r+1;
404
+
405
+	for (;;) {
406
+	  while (V[++i] < m);
407
+	  while (V[--j] > m);
408
+	  if (i >= j) break;
409
+	  std::swap(index[i], index[j]);
410
+	  std::swap(V[i--], V[j++]); // restart from indices i and j just used, in case one is pivot
411
+	}
412
+
413
+	(*this).QuickSort(index, l, i-1);
414
+	(*this).QuickSort(index, i+1, r);
415
+      }
416
+
417
+    }
418
+  */
419
+
420
+  template <class T>
421
+    void Vect<T>::QuickSort (Vect<int>& index, int l, int r)
422
+    {
423
+      int i = l, j = r;
424
+      T pivot = V[l + (r-l)/2];
425
+      
426
+      while (i <= j) {
427
+	while (V[i] < pivot) i++;
428
+	while (V[j] > pivot) j--;
429
+	if (i <= j) {
430
+	  std::swap(V[i],V[j]);
431
+	  std::swap(index[i],index[j]);
432
+	  i++;
433
+	  j--;
434
+	}
435
+      };
436
+      
437
+      if (l < j) (*this).QuickSort(index, l, j);
438
+      if (i < r) (*this).QuickSort(index, i, r);
439
+    }
440
+
441
+  template <class T>
442
+    void Vect<T>::QuickSort (Vect<int>& index)
443
+    {
444
+      if (index.size() != (*this).size()) JSCerror("Wrong dim for index in Vect QuickSort.");
445
+      (*this).QuickSort (index, 0, (*this).size() - 1);
446
+    }
447
+
448
+  template <class T>
449
+  inline std::ostream& operator<< (std::ostream& s, const Vect<T>& vector)
450
+  {
451
+    for (int i = 0; i < vector.size() - 1; ++i) s << vector[i] << " ";
452
+    if (vector.size() >= 1) s << vector[vector.size() - 1];
453
+
454
+    return (s);
455
+  }
456
+
457
+  template <class T>
458
+    Vect<T>::~Vect<T>()
459
+  {
460
+    if (V != 0) delete[] V;
461
+  }
462
+
463
+
464
+  // TYPEDEFS  
465
+  typedef JSC::Vect<int> Vect_INT;
466
+  typedef JSC::Vect<double> Vect_DP;
467
+  typedef JSC::Vect<complex<double> > Vect_CX;
468
+
469
+  
470
+} // namespace JSC
471
+
472
+#endif

+ 139
- 0
include/JSC_XXX_h0.h View File

@@ -0,0 +1,139 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_XXX_h0.h
10
+
11
+Purpose:  Declares classes for XXX in zero field:  Uq(sl(2)) stuff.
12
+
13
+
14
+***********************************************************/
15
+
16
+#ifndef _XXX_h0_
17
+#define _XXX_h0_
18
+
19
+#include "JSC.h"
20
+
21
+const DP default_req_prec = 1.0e-14;
22
+const int default_max_rec = 10;
23
+
24
+namespace JSC {
25
+
26
+  inline DP Integrand_11 (Vect_DP args)
27
+    {
28
+      // args[0] corresponds to t, args[1] to rho
29
+      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]);
30
+    }
31
+  
32
+  inline DP Integrand_12 (Vect_DP args)
33
+    {
34
+      DP expm2t = exp(-2.0*args[0]);
35
+      return(cos(4.0 * args[0] * args[1]) * expm2t * (3.0 + expm2t)/ (args[0] * (1.0 + expm2t) * (1.0 + expm2t)));
36
+    }
37
+  
38
+  inline DP Integrand_2 (Vect_DP args)
39
+    {
40
+      DP answer = 0.0;
41
+      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));
42
+      else if (args[0] >= 1.0) {
43
+	DP expm2t = exp(-2.0 * args[0]);
44
+	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));
45
+      }
46
+      return(answer);
47
+    }
48
+  
49
+  inline DP Integrand_A (Vect_DP args)
50
+    {
51
+      // This kernel is for -ln | A_-(i\pi/2) | function
52
+      return(exp(args[0]) * pow(sinh(args[0]/2.0), 2.0)/(args[0] * sinh(2.0*args[0]) * cosh(args[0])));
53
+    }
54
+  
55
+  DP I_integral (DP rho, DP req_prec);
56
+
57
+
58
+  /*********************  TWO SPINONS ********************/
59
+
60
+  DP SF_2p (DP k, DP omega, I_table Itable);
61
+  DP SF_2p (Vect_DP args, I_table Itable);
62
+  DP SF_2p_alt (Vect_DP args, I_table Itable);
63
+  DP SF_2p_w (Vect_DP args, I_table Itable);
64
+  DP SF_2p_w_alt (Vect_DP args, I_table Itable);
65
+  DP SF_2p_intw (Vect_DP args, I_table Itable);
66
+  DP SF_2p_intw_alt (Vect_DP args, I_table Itable);
67
+  DP SF_2p_check_sumrule (DP req_prec, int max_rec, I_table Itable);
68
+  DP SF_2p_check_sumrule_alt (DP req_prec, int max_rec, I_table Itable);
69
+  DP Fixed_k_sumrule_w (DP k);
70
+  DP Fixed_k_sumrule_omega (DP k);
71
+  DP SF_2p_check_fixed_k_sumrule (DP k, DP req_prec, int max_rec, I_table Itable);
72
+  DP SF_2p_check_fixed_k_sumrule_alt (DP k, DP req_prec, int max_rec, I_table Itable);
73
+  DP SF_2p_check_fixed_k_sumrule_opt (DP k, DP req_prec, int Npts, I_table Itable);
74
+
75
+
76
+/********************** FOUR SPINONS **********************/
77
+
78
+  DP Sum_norm_gl (Vect_DP rho, DP req_prec);
79
+  DP Compute_C4 (DP req_prec);
80
+  DP SF_contrib (Vect_DP p, DP req_prec, I_table Itable);
81
+  DP J_fn (Vect_DP p, DP req_prec, I_table Itable);
82
+  inline DP Jacobian_p3p4_KW (DP k, DP w, DP K, DP W)
83
+    {
84
+      return(1.0/sqrt(pow(twoPI * sin(0.5 * (k - K)), 2.0) - (w-W)*(w-W)));
85
+    }
86
+  bool Set_p_given_kwKW (DP k, DP w, DP K, DP W, Vect_DP& p);
87
+  inline DP wmin_4p (DP k)
88
+  {
89
+    return(PI * fabs(sin(k)));
90
+  }  
91
+  inline DP wmax_4p (DP k)
92
+  {
93
+    return(2.0 * PI * sqrt(2.0 * (1.0 + fabs(cos(0.5*k)))));
94
+  }
95
+  inline  DP Wmin (DP k, DP w, DP K)
96
+  {
97
+    return(JSC::max(1.0e-15, JSC::max(fabs(PI * sin(K)), w - twoPI * sin(0.5 * (fabs(k-K))))));
98
+  }
99
+  inline  DP Wmax (DP k, DP w, DP K)
100
+  {
101
+    return(JSC::min(twoPI * sin(0.5 * K), w - fabs(PI * sin(k - K))));
102
+  }
103
+  DP G_fn (Vect_DP args_to_G, I_table Itable);
104
+  DP G1_fn (Vect_DP args_to_G, I_table Itable);
105
+  DP G2_fn (Vect_DP args_to_G, I_table Itable);
106
+  DP G1_fn_mid (Vect_DP args_to_G, I_table Itable);
107
+  DP G2_fn_mid (Vect_DP args_to_G, I_table Itable);
108
+  DP G_fn_alt (Vect_DP args_to_G, I_table Itable);
109
+  DP H_fn (Vect_DP args_to_H, I_table Itable);
110
+  DP H2_fn (Vect_DP args_to_H, I_table Itable);
111
+  DP H_fn_mid (Vect_DP args_to_H, I_table Itable);
112
+  DP H_fn_alt (Vect_DP args_to_H, I_table Itable);
113
+  DP SF_4p_kwKW (Vect_DP args, I_table Itable);
114
+  DP SF_4p_kwKW_alpha (Vect_DP args, I_table Itable);
115
+  DP SF_4p_kwKW_alpha_opt (Vect_DP args, I_table Itable);
116
+
117
+  // Interface to used version:
118
+  DP SF_4p_rec (DP k, DP omega, DP req_prec, int max_rec, I_table Itable);
119
+  DP SF_4p (DP k, DP omega, I_table Itable);
120
+  DP SF_4p_opt (DP k, DP omega, DP req_prec, int Npts_K, int Npts_W, I_table Itable);
121
+  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);
122
+  DP SF_4p_rec (DP k, DP req_prec, int max_rec_w, int max_rec, I_table Itable);
123
+  Integral_result SF_4p_opt (DP k, DP req_prec, int Npts, I_table Itable);
124
+  Integral_result SF_4p_opt (DP k, DP req_prec, int Npts_w, int Npts_KW, I_table Itable);
125
+  Integral_result SF_4p_opt (DP k, DP req_prec, int Npts_w, int Npts_K, int Npts_W, I_table Itable);
126
+
127
+  //******************************** Functions to produce files similar to ABACUS **********************************
128
+  void Produce_SF_2p_file (int N, int Nomega, DP omegamax, I_table Itable);
129
+  void Produce_SF_4p_file (int N, int Nomega, DP omegamax, DP req_prec, int max_rec, I_table Itable);
130
+  void Produce_SF_4p_file (int N, int Nomega, DP omegamax, DP req_prec, int Npts_K, int Npts_W, I_table Itable);
131
+
132
+  //******************************** New version, full k and omega integral in one go ******************************
133
+  DP Direct_J_integral (int Npts_p, DP req_prec, I_table Itable);
134
+  DP Direct_J_integral_bin (int Npts_p, int Npts_o, DP req_prec, I_table Itable);
135
+  void Smoothen_raw_SF_4p (int Npts_p, int Npts_o, DP req_prec, DP width);
136
+
137
+} // namespace JSC
138
+
139
+#endif

+ 86
- 0
include/JSC_XXZ_h0.h View File

@@ -0,0 +1,86 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_XXZ_h0.h
10
+
11
+Purpose:  Declares classes for XXZ in zero field:  quantum group stuff.
12
+
13
+
14
+***********************************************************/
15
+
16
+#ifndef _XXZ_h0_
17
+#define _XXZ_h0_
18
+
19
+#include "JSC.h"
20
+
21
+//const DP default_req_prec = 1.0e-14;
22
+//const int default_max_rec = 10;
23
+
24
+namespace JSC {
25
+
26
+  /*
27
+  inline DP Integrand_xi_11 (Vect_DP args)
28
+    {
29
+      // args[0] corresponds to t, args[1] to rho, args[2] to xi
30
+      //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]);
31
+      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)) 
32
+	      + 2.0 * pow(sin(2.0 * args[0] * args[1]), 2.0))/args[0]);
33
+    }
34
+  
35
+  inline DP Integrand_xi_12 (Vect_DP args)
36
+    {
37
+      DP expm2t = exp(-2.0*args[0]);
38
+      DP expm2txi = exp(-2.0*args[0]*args[2]);
39
+      //return(cos(4.0 * args[0] * args[1]) * expm2t * (3.0 + expm2t)/ (args[0] * (1.0 + expm2t) * (1.0 + expm2t)));
40
+      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)));
41
+    }
42
+  */
43
+  /*  
44
+  inline DP Integrand_xi_2 (Vect_DP args)
45
+    {
46
+      DP answer = 0.0;
47
+      if (args[0] < 1.0) 
48
+	//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));
49
+	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));
50
+      else if (args[0] >= 1.0) {
51
+	DP expm2t = exp(-2.0 * args[0]);
52
+	DP expm2txi = exp(-2.0*args[0]*args[2]);
53
+	//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));
54
+	answer = 8.0 * ((1.0 - expm2t*expm2txi)/(1.0 - expm2t*expm2txi)) * expm2t * 
55
+	  pow(sin(2.0 * args[0] * args[1]), 2.0)/(args[0] * (1.0 - expm2t) * (1.0 + expm2t) * (1.0 + expm2t));
56
+      }
57
+      return(answer);
58
+    }
59
+  */
60
+
61
+  DP I_xi_integral (DP xi, DP rho, DP req_prec, int max_nr_pts);
62
+
63
+
64
+  /*********************  TWO SPINONS ********************/
65
+  DP Szz_XXZ_h0_2spinons (DP k, DP omega, Integral_table Itable);
66
+  DP Szz_XXZ_h0_2spinons (Vect_DP args, Integral_table Itable);
67
+  DP Szz_XXZ_h0_2spinons_alt (Vect_DP args, Integral_table Itable);
68
+  DP Szz_XXZ_h0_2spinons_omega (Vect_DP args, Integral_table Itable);
69
+  DP Szz_XXZ_h0_2spinons_omega_alt (Vect_DP args, Integral_table Itable);
70
+  DP Szz_XXZ_h0_2spinons_intomega (Vect_DP args, Integral_table Itable);
71
+  DP Szz_XXZ_h0_2spinons_intomega_alt (Vect_DP args, Integral_table Itable);
72
+  DP Szz_XXZ_h0_2spinons_check_sumrule (DP Delta, DP req_prec, int max_nr_pts, Integral_table Itable);
73
+  DP Szz_XXZ_h0_2spinons_check_sumrule_alt (DP Delta, DP req_prec, int max_nr_pts, Integral_table Itable);
74
+  DP Fixed_k_sumrule_omega_Szz_XXZ_h0_N (DP Delta, DP k);
75
+  DP GSE_XXZ_h0 (DP Delta, DP req_prec, int max_nr_pts);
76
+  DP Fixed_k_sumrule_omega_Szz_XXZ_h0 (DP Delta, DP k, DP req_prec, int max_nr_pts);
77
+  DP Szz_XXZ_h0_2spinons_check_fixed_k_Szz_sumrule (DP Delta, DP k, DP req_prec, int max_nr_pts, Integral_table Itable);
78
+  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);
79
+
80
+  //******************************** Functions to produce files similar to ABACUS **********************************
81
+  void Produce_Szz_XXZ_h0_2spinons_file (DP Delta, int N, int Nomega, DP omegamax, Integral_table Itable);
82
+  void Produce_Szz_XXZ_h0_2spinons_fixed_K_file (DP Delta, DP Kover2PI, int Nomega, Integral_table Itable);
83
+
84
+} // namespace JSC
85
+
86
+#endif

+ 118
- 0
include/JSC_Young.h View File

@@ -0,0 +1,118 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_Young.h
10
+
11
+Purpose:  Declares Young tableau class.
12
+
13
+***********************************************************/
14
+
15
+#ifndef _YOUNG_
16
+#define _YOUNG_
17
+
18
+#include "JSC_Vect.h"
19
+
20
+namespace JSC {
21
+
22
+  const int YOUNG_TABLEAU_ID_OPTION = 0;
23
+  const long long int TABLEAU_ID_UPPER_LIMIT = 10000000LL;
24
+
25
+  //***********************************************************************
26
+
27
+  class Young_Tableau {
28
+
29
+  public:
30
+    int Nrows;
31
+    int Ncols;
32
+    int* Row_L;
33
+    int* Col_L;
34
+    long long int id;     // identification number
35
+    long long int maxid;  
36
+    long long int* map;
37
+    bool map_computed;
38
+    long long int idnr_reached;
39
+    int nboxes_reached;
40
+
41
+  private:
42
+    int dimchoose;
43
+    long long int* choose_table;
44
+
45
+  public:
46
+    Young_Tableau ();    // empty constructor, does nothing
47
+    Young_Tableau (int Nr, int Nc);  // constructs empty tableau
48
+    Young_Tableau (int Nr, int Nc, long long int idnr);  // constructs the tableau corresponding to identification number idnr
49
+    Young_Tableau (const Young_Tableau& RefTableau);  // copy constructor
50
+    Young_Tableau (int Nr, int Nc, const Young_Tableau& RefTableau);
51
+    Young_Tableau& operator= (const Young_Tableau& RefTableau);  // assignment
52
+    ~Young_Tableau ();  // destructor
53
+
54
+  public:
55
+    Young_Tableau& Compute_Map (long long int idnr_to_reach);  // fills the map vector
56
+    Young_Tableau& Distribute_boxes (int nboxes_to_dist, int level);
57
+    Young_Tableau& Set_to_id (long long int idnr); // sets the tableau to the one corresponding to idnr
58
+    Young_Tableau& Set_to_id (long long int idnr, int option); // sets the tableau to the one corresponding to idnr according to rule option
59
+    Young_Tableau& Set_Row_L (Vect<int>& Row_Lengths);  // set row lengths
60
+    Young_Tableau& Set_Col_L_given_Row_L ();   // sets the Col_L array self-consistently
61
+    Young_Tableau& Set_Row_L_given_Col_L ();   // sets the Col_L array self-consistently
62
+    long long int Compute_Descendent_id (int option, Vect<int>& Desc_Row_L, int Nrows_Desc, int Ncols_Desc, 
63
+					 const Young_Tableau& RefTableau);
64
+    Young_Tableau& Compute_id();       // computes the id number of tableau
65
+    Young_Tableau& Compute_id(int option);       // computes the id number of tableau according to rule option
66
+    Young_Tableau& Print();            // couts the tableau 
67
+
68
+    bool Lower_Row (int i);
69
+    bool Raise_Row (int i);
70
+    bool Lower_Col (int i);
71
+    bool Raise_Col (int i);
72
+    bool Raise_Lowest_Nonzero_Row(); // adds a box to the lowest nonzero length Row, recomputes id, returns true if tableau has changed
73
+    bool Raise_Next_to_Lowest_Nonzero_Row(); // same thing, but for Row under lowest nonzero length one.
74
+    bool Move_Box_from_Col_to_Col (int ifrom, int ito);
75
+
76
+    Vect<Young_Tableau> Descendents (int fixed_Nboxes);
77
+    Vect<Young_Tableau> Descendents_Boosted_State (int fixed_Nboxes);
78
+
79
+    int Add_Boxes_From_Lowest (int Nboxes);  // tries to add Nboxes to Tableau, returns number of boxes added.
80
+  };
81
+
82
+  std::ostream& operator<< (std::ostream& s, const Young_Tableau& tableau);
83
+
84
+  inline int Nr_Nonzero_Rows (const Vect<Young_Tableau>& Tableau_ref)
85
+  {
86
+    // This function checks the number of rows containing at least one box
87
+    // in the whole vector of Young tableaux given as argument.
88
+    // The usefulness is to force descent of states in which only a few
89
+    // excitations have started dispersing.
90
+
91
+    int nr_nonzero_rows = 0;
92
+    for (int i = 0; i < Tableau_ref.size(); ++i)
93
+      for (int alpha = 0; alpha < Tableau_ref[i].Nrows; ++alpha)
94
+	if (Tableau_ref[i].Row_L[alpha] > 0) nr_nonzero_rows++;
95
+
96
+    return(nr_nonzero_rows);
97
+  }
98
+
99
+  //***********************************************************************
100
+
101
+  class Tableau_Map {
102
+
103
+  public:
104
+    Vect<long long int> map;
105
+    long long int idnr_reached;
106
+    int nboxes_reached;
107
+    
108
+  public:
109
+    Tableau_Map (int Nrows, int Ncols);
110
+    void Distribute_id (int nboxes_to_dist, int level, Young_Tableau& RefTableau);
111
+    
112
+  };
113
+
114
+
115
+
116
+} // namespace JSC
117
+
118
+#endif

+ 485
- 0
include/JSC_util.h View File

@@ -0,0 +1,485 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  JSC_util.h
10
+
11
+Purpose:  Defines basic math functions.
12
+
13
+***********************************************************/
14
+
15
+#ifndef _JSC_UTIL_H_
16
+#define _JSC_UTIL_H_
17
+
18
+#include "JSC.h"
19
+
20
+using namespace std;
21
+
22
+typedef double DP;
23
+
24
+// Global constants
25
+
26
+const double PI = 3.141592653589793238462643;
27
+const double sqrtPI = sqrt(PI);
28
+const double twoPI = 2.0*PI;
29
+const double logtwoPI = log(twoPI);
30
+const double Euler_Mascheroni = 0.577215664901532860606;
31
+const double Gamma_min_0p5 = -2.0 * sqrt(PI);
32
+const complex<double> II(0.0,1.0);  //  Shorthand for i
33
+
34
+const DP MACHINE_EPS = numeric_limits<DP>::epsilon();
35
+const DP MACHINE_EPS_SQ = pow(MACHINE_EPS, 2.0);
36
+
37
+// Now for some basic math utilities:
38
+
39
+namespace JSC {
40
+
41
+  // File checks:
42
+
43
+  inline bool file_exists (const char* filename)
44
+  {
45
+    fstream file;
46
+    file.open(filename);
47
+    bool exists = !file.fail();
48
+    file.close();
49
+
50
+    return(exists);
51
+  }
52
+    
53
+  // Error handler:
54
+    
55
+  inline void JSCerror (const string error_text)
56
+  // my error handler
57
+  {
58
+    cerr << "Run-time error... " << endl;
59
+    cerr << error_text << endl;
60
+    cerr << "Exiting to system..." << endl;
61
+    exit(1);
62
+  }
63
+
64
+  struct Divide_by_zero {};
65
+
66
+
67
+  // Basics:  min, max, fabs
68
+
69
+  template<class T> 
70
+    inline const T max (const T& a, const T& b) { return a > b ? (a) : (b); }
71
+  
72
+  template<class T> 
73
+    inline const T min (const T& a, const T& b) { return a > b ? (b) : (a); }
74
+  
75
+  template<class T>
76
+    inline const T fabs (const T& a) { return a >= 0 ? (a) : (-a); }
77
+
78
+  inline long long int pow_lli (const long long int& base, const int& exp)
79
+    { 
80
+      long long int answer = base;
81
+      if (exp == 0) answer = 1LL;
82
+      else for (int i = 1; i < exp; ++i) answer *= base;
83
+      return(answer);
84
+    }
85
+
86
+  inline unsigned long long int pow_ulli (const unsigned long long int& base, const int& exp)
87
+    { 
88
+      unsigned long long int answer = base;
89
+      if (exp == 0) answer = 1ULL;
90
+      for (int i = 1; i < exp; ++i) answer *= base;
91
+      return(answer);
92
+    }
93
+
94
+  inline int fact (const int& N)
95
+    {
96
+      int ans = 0;
97
+
98
+      if (N < 0) {
99
+	cerr << "Error:  factorial of negative number.  Exited." << endl;
100
+	exit(1);
101
+      }
102
+      else if ( N == 1  ||  N == 0) ans = 1;
103
+      else ans = N * fact(N-1);
104
+
105
+      return(ans);
106
+    }
107
+
108
+  inline DP ln_fact (const int& N)
109
+    {
110
+      DP ans = 0.0;
111
+
112
+      if (N < 0) {
113
+	cerr << "Error:  factorial of negative number.  Exited." << endl;
114
+	exit(1);
115
+      }
116
+      else if ( N == 1  ||  N == 0) ans = 0.0;
117
+      else ans = log(DP(N)) + ln_fact(N-1);
118
+
119
+      return(ans);
120
+    }
121
+
122
+    inline long long int fact_lli (const int& N)
123
+    {
124
+      long long int ans = 0;
125
+
126
+      if (N < 0) {
127
+	cerr << "Error:  factorial of negative number.  Exited." << endl;
128
+	exit(1);
129
+      }
130
+      else if ( N == 1  ||  N == 0) ans = 1;
131
+      else ans = fact_lli(N-1) * N;
132
+
133
+      return(ans);
134
+    }
135
+
136
+    inline long long int fact_ulli (const int& N)
137
+    {
138
+      unsigned long long int ans = 0;
139
+
140
+      if (N < 0) {
141
+	cerr << "Error:  factorial of negative number.  Exited." << endl;
142
+	exit(1);
143
+      }
144
+      else if ( N == 1  ||  N == 0) ans = 1;
145
+      else ans = fact_ulli(N-1) * N;
146
+
147
+      return(ans);
148
+    }
149
+
150
+    inline int choose (const int& N1, const int& N2)
151
+    {
152
+      // returns N1 choose N2
153
+
154
+      int ans = 0;
155
+      if (N1 < N2) {
156
+	cout << "Error:  N1 smaller than N2 in choose.  Exited." << endl;
157
+	exit(1);
158
+      }
159
+      else if (N1 == N2) ans = 1;
160
+      else if (N1 < 12) ans = fact(N1)/(fact(N2) * fact(N1 - N2));
161
+      else {
162
+	ans = 1;
163
+	int mult = N1;
164
+	while (mult > max(N2, N1 - N2)) ans *= mult--;
165
+	ans /= fact(min(N2, N1 - N2));
166
+      }
167
+
168
+      return(ans);
169
+    }
170
+
171
+    inline DP ln_choose (const int& N1, const int& N2)
172
+    {
173
+      // returns the log of N1 choose N2
174
+
175
+      DP ans = 0.0;
176
+      if (N1 < N2) {
177
+	cout << "Error:  N1 smaller than N2 in choose.  Exited." << endl;
178
+	exit(1);
179
+      }
180
+      else if (N1 == N2) ans = 0.0;
181
+      else ans = ln_fact(N1) - ln_fact(N2) - ln_fact(N1 - N2);
182
+
183
+      return(ans);
184
+    }
185
+
186
+
187
+    inline long long int choose_lli (const int& N1, const int& N2)
188
+    {
189
+      // returns N1 choose N2
190
+
191
+      long long int ans = 0;
192
+      if (N1 < N2) {
193
+	cout << "Error:  N1 smaller than N2 in choose.  Exited." << endl;
194
+	exit(1);
195
+      }
196
+      else if (N1 == N2) ans = 1;
197
+      else if (N1 < 12) ans = fact_lli(N1)/(fact_lli(N2) * fact_lli(N1 - N2));
198
+      else {
199
+	// Make sure that N2 is less than or equal to N1/2;  if not, just switch...
200
+	int N2_min = min(N2, N1 - N2);
201
+
202
+	ans = 1;
203
+	for (int i = 0; i < N2_min; ++i) {
204
+	  ans *= (N1 - i);
205
+	  ans /= i + 1;
206
+	}
207
+      }
208
+
209
+      return(ans);
210
+    }
211
+
212
+    inline unsigned long long int choose_ulli (const int& N1, const int& N2)
213
+    {
214
+      // returns N1 choose N2
215
+
216
+      unsigned long long int ans = 0;
217
+      if (N1 < N2) {
218
+	cout << "Error:  N1 smaller than N2 in choose.  Exited." << endl;
219
+	exit(1);
220
+      }
221
+      else if (N1 == N2) ans = 1;
222
+      else if (N1 < 12) ans = fact_ulli(N1)/(fact_ulli(N2) * fact_ulli(N1 - N2));
223
+      else {
224
+	// Make sure that N2 is less than or equal to N1/2;  if not, just switch...
225
+	int N2_min = min(N2, N1 - N2);
226
+
227
+	ans = 1;
228
+	for (int i = 0; i < N2_min; ++i) {
229
+	  ans *= (N1 - i);
230
+	  ans /= i + 1;
231
+	}
232
+      }
233
+
234
+      return(ans);
235
+    }
236
+
237
+    inline DP SIGN (const DP &a, const DP &b) 
238
+    {
239
+      return b >= 0 ? (a >= 0 ? a : -a) : (a >= 0 ? -a : a);
240
+    }
241
+
242
+    inline DP sign_of (const DP& a)
243
+    {
244
+      return (a >= 0.0 ? 1.0 : -1.0);
245
+    }
246
+
247
+    inline int sgn_int (const int& a)
248
+    {
249
+      return (a >= 0) ? 1 : -1;
250
+    }
251
+
252
+    inline int sgn_DP (const DP& a)
253
+    {
254
+      return (a >= 0) ? 1 : -1;
255
+    }
256
+
257
+    template<class T>
258
+    inline void SWAP (T& a, T& b) {T dum = a; a = b; b = dum;}
259
+
260
+    inline int kronecker (int a, int b) 
261
+      {
262
+	return a == b ? 1 : 0;
263
+      }
264
+
265
+    template<class T>
266
+    inline bool is_nan (const T& a)
267
+      {
268
+	return(!((a < T(0.0)) || (a >= T(0.0))));
269
+      }
270
+
271
+    inline complex<DP> atan_cx(const complex<DP>& x)
272
+      {
273
+	return(-0.5 * II * log((1.0 + II* x)/(1.0 - II* x)));
274
+      }
275
+
276
+    /****************  Gamma function *******************/
277
+
278
+    inline complex<double> ln_Gamma (complex<double> z)
279
+      {
280
+	// Implementation of Lanczos method with g = 9.
281
+	// Coefficients from Godfrey 2001.
282
+	
283
+	if (real(z) < 0.5) return(log(PI/(sin(PI*z))) - ln_Gamma(1.0 - z));
284
+	
285
+	else {
286
+
287
+	  complex<double> series = 1.000000000000000174663
288
+	    + 5716.400188274341379136/z 
289
+	    - 14815.30426768413909044/(z + 1.0)
290
+	    + 14291.49277657478554025/(z + 2.0)
291
+	    - 6348.160217641458813289/(z + 3.0)
292
+	    + 1301.608286058321874105/(z + 4.0)
293
+	    - 108.1767053514369634679/(z + 5.0)
294
+	    + 2.605696505611755827729/(z + 6.0)
295
+	    - 0.7423452510201416151527e-2 / (z + 7.0)
296
+	    + 0.5384136432509564062961e-7 / (z + 8.0)
297
+	    - 0.4023533141268236372067e-8 / (z + 9.0);
298
+	  
299
+	  return(0.5 * logtwoPI + (z - 0.5) * log(z + 8.5) - (z + 8.5) + log(series));
300
+	}
301
+	
302
+	return(log(0.0));  // never called
303
+      }
304
+
305
+    inline complex<double> ln_Gamma_old (complex<double> z)
306
+      {
307
+	// Implementation of Lanczos method with g = 9.
308
+	// Coefficients from Godfrey 2001.
309
+	
310
+	if (real(z) < 0.5) return(log(PI/(sin(PI*z))) - ln_Gamma(1.0 - z));
311
+	
312
+	else {
313
+	  
314
+	  int g = 9;
315
+	  
316
+	  double p[11] = { 1.000000000000000174663,
317
+			   5716.400188274341379136, 
318
+			   -14815.30426768413909044,
319
+			   14291.49277657478554025,
320
+			   -6348.160217641458813289,
321
+			   1301.608286058321874105,
322
+			   -108.1767053514369634679,
323
+			   2.605696505611755827729,
324
+			   -0.7423452510201416151527e-2,
325
+			   0.5384136432509564062961e-7,
326
+			   -0.4023533141268236372067e-8 };
327
+	  
328
+	  complex<double> z_min_1 = z - 1.0;
329
+	  complex<double> series = p[0];
330
+	  for (int i = 1; i < g+2; ++i)
331
+	    series += p[i]/(z_min_1 + complex<double>(i));
332
+	  
333
+	  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));
334
+	}
335
+	
336
+	return(log(0.0));  // never called
337
+      }
338
+
339
+    inline complex<double> ln_Gamma_2 (complex<double> z)
340
+      {
341
+	// Implementation of Lanczos method with g = 7.
342
+	
343
+	if (real(z) < 0.5) return(log(PI/(sin(PI*z)) - ln_Gamma(1.0 - z)));
344
+	
345
+	else {
346
+	  
347
+	  int g = 7;
348
+	  
349
+	  double p[9] = { 0.99999999999980993, 676.5203681218851, -1259.1392167224028,
350
+			  771.32342877765313, -176.61502916214059, 12.507343278686905,
351
+			  -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7};
352
+	  
353
+	  complex<double> z_min_1 = z - 1.0;
354
+	  complex<double> series = p[0];
355
+	  for (int i = 1; i < g+2; ++i)
356
+	    series += p[i]/(z_min_1 + complex<double>(i));
357
+
358
+	  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));
359
+	}
360
+	
361
+	return(log(0.0));  // never called
362
+      }
363
+
364
+    /**********  Partition numbers **********/
365
+
366
+    inline long long int Partition_Function (int n)
367
+    {
368
+      // Returns the value of the partition function p(n), giving the number of partitions of n into integers.
369
+
370
+      if (n < 0) JSCerror("Calling Partition_Function for n < 0.");
371
+      else if (n == 0 || n == 1) return(1LL);
372
+      else if (n == 2) return(2LL);
373
+      else if (n == 3) return(3LL);
374
+
375
+      else {  // do recursion using pentagonal numbers
376
+	long long int pn = 0LL;
377
+	int pentnrplus, pentnrmin;  // pentagonal numbers
378
+	for (int i = 1; true; ++i) {
379
+	  pentnrplus = (i * (3*i - 1))/2;
380
+	  pentnrmin = (i * (3*i + 1))/2;
381
+	  //cout << "\ti = " << i << "pnrp = " << pentnrplus << "\tpnrm = " << pentnrmin << endl;
382
+	  if (n - pentnrplus >= 0) pn += (i % 2 ? 1LL : -1LL) * Partition_Function (n - pentnrplus);
383
+	  if (n - pentnrmin >= 0) pn += (i % 2 ? 1LL : -1LL) * Partition_Function (n - pentnrmin);
384
+	  else break;
385
+	}
386
+	return(pn);
387
+      }
388
+      return(-1LL);  // never called
389
+    }
390
+
391
+
392
+    /**********  Sorting **********/
393
+
394
+    /*
395
+    template<class item_type>
396
+      void QuickSort (item_type* a, int l, int r)
397
+      {
398
+	static item_type m;
399
+	static int j;
400
+	int i;
401
+	
402
+	if (r > l) {
403
+	  m = a[r]; i = l-1; j = r;
404
+	  for (;;) {
405
+	    while (a[++i] < m);
406
+	    while (a[--j] > m);
407
+	    if (i >= j) break;
408
+	    std::swap(a[i], a[j]);
409
+	  }
410
+	  std::swap(a[i], a[r]);
411
+	  QuickSort(a, l, i-1);
412
+	  QuickSort(a, i+1, r);
413
+	}
414
+      }
415
+    */
416
+
417
+  template <class T>
418
+    void QuickSort (T* V, int l, int r)
419
+    {
420
+      int i = l, j = r;
421
+      T pivot = V[l + (r-l)/2];
422
+      
423
+      while (i <= j) {
424
+	while (V[i] < pivot) i++;
425
+	while (V[j] > pivot) j--;
426
+	if (i <= j) {
427
+	  std::swap(V[i],V[j]);
428
+	  i++;
429
+	  j--;
430
+	}
431
+      };
432
+      
433
+      if (l < j) QuickSort(V, l, j);
434
+      if (i < r) QuickSort(V, i, r);
435
+    }
436
+    
437
+  /*
438
+    template<class item_type> 
439
+      void QuickSort (item_type* a, int* idx, int l, int r)
440
+      {
441
+	static item_type m;
442
+	static int j;
443
+	int i;
444
+	
445
+	if (r > l) {
446
+	  m = a[r]; i = l-1; j = r;
447
+	  for (;;) {
448
+	    while (a[++i] < m);
449
+	    while (a[--j] > m);
450
+	    if (i >= j) break;
451
+	    std::swap(a[i], a[j]);
452
+	    std::swap(idx[i], idx[j]);
453
+	  }
454
+	  std::swap(a[i], a[r]);
455
+	  std::swap(idx[i], idx[r]);
456
+	  QuickSort(a, idx, l, i-1);
457
+	  QuickSort(a, idx, i+1, r);
458
+	}
459
+      }
460
+  */
461
+  template <class T>
462
+    void QuickSort (T* V, int* index, int l, int r)
463
+    {
464
+      int i = l, j = r;
465
+      T pivot = V[l + (r-l)/2];
466
+      
467
+      while (i <= j) {
468
+	while (V[i] < pivot) i++;
469
+	while (V[j] > pivot) j--;
470
+	if (i <= j) {
471
+	  std::swap(V[i],V[j]);
472
+	  std::swap(index[i],index[j]);
473
+	  i++;
474
+	  j--;
475
+	}
476
+      };
477
+      
478
+      if (l < j) QuickSort(V, index, l, j);
479
+      if (i < r) QuickSort(V, index, i, r);
480
+    }
481
+
482
+
483
+} // namespace JSC
484
+
485
+#endif // _JS_UTIL_H_

+ 307
- 0
src/BETHE/Base.cc View File

@@ -0,0 +1,307 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+-----------------------------------------------------------
6
+
7
+File:  src/BETHE/Base.cc
8
+
9
+Purpose:  defines functions in Base class,
10
+          providing a unified base object for all
11
+          Bethe Ansatz integrable models.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+
20
+namespace JSC {
21
+
22
+  // Function definitions:  class Base
23
+
24
+  Base::Base () : Charge(0), Nrap(Vect<int>()), Nraptot(0), Ix2_infty(Vect<DP>()),
25
+		  Ix2_max(Vect<int>()), id(0LL) {}
26
+  
27
+  Base::Base (int N) : Charge(N), Nrap(Vect<int>(N,1)), Nraptot(N), Ix2_infty(Vect<DP>(1.0e+100,1)),
28
+		       Ix2_max(Vect<int>(LONG_LONG_MAX, 1)), id(N) {}
29
+
30
+  Base::Base (const Base& RefBase)  // copy constructor
31
+    : Charge(RefBase.Charge), Nrap(Vect<int>(RefBase.Nrap.size())), Nraptot(RefBase.Nraptot), 
32
+      Ix2_infty(Vect<DP>(RefBase.Ix2_infty.size())), Ix2_max(Vect<int>(RefBase.Ix2_max.size())), id(RefBase.id) 
33
+  {
34
+    for (int i = 0; i < Nrap.size(); ++i) {
35
+      Nrap[i] = RefBase.Nrap[i];
36
+      Ix2_infty[i] = RefBase.Ix2_infty[i];
37
+      Ix2_max[i] = RefBase.Ix2_max[i];
38
+    }
39
+  }
40
+
41
+  /*
42
+  // DEPRECATED
43
+  Base::Base (const Heis_Chain& RefChain, int M) 
44
+    : Charge(M), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings))
45
+  {
46
+    for (int i = 0; i < RefChain.Nstrings; ++i) Nrap[i] = 0;
47
+    Nrap[0] = M;
48
+
49
+    Nraptot = 0;
50
+    for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
51
+    
52
+    // The id of this is zero by definition
53
+    id = 0LL;
54
+
55
+    // Now compute the Ix2_infty numbers
56
+    
57
+    (*this).Compute_Ix2_limits(RefChain);
58
+
59
+  }
60
+  */
61
+  Base::Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities) 
62
+    : Charge(0), Nrap(Nrapidities), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)),
63
+      id (0LL)
64
+  {
65
+
66
+    // Check consistency of Nrapidities vector with RefChain
67
+
68
+    //if (RefChain.Nstrings != Nrapidities.size()) cout << "error:  Nstrings = " << RefChain.Nstrings << "\tNrap.size = " << Nrapidities.size() << endl;
69
+    
70
+    if (RefChain.Nstrings != Nrapidities.size()) JSCerror("Incompatible Nrapidities vector used in Base constructor.");
71
+    
72
+    int Mcheck = 0;
73
+    for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
74
+    Charge = Mcheck;
75
+    
76
+    Nraptot = 0;
77
+    for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
78
+    
79
+    // Compute id
80
+    id += Nrapidities[0];
81
+    long long int factor = 100000LL;
82
+    for (int i = 1; i < RefChain.Nstrings; ++i) {
83
+      id += factor * Nrapidities[i];
84
+      factor *= 100LL;
85
+    }
86
+
87
+    // Now compute the Ix2_infty numbers
88
+
89
+    (*this).Compute_Ix2_limits(RefChain);
90
+    
91
+  }
92
+
93
+  Base::Base (const Heis_Chain& RefChain, long long int id_ref) 
94
+    : Charge(0), Nrap(Vect<int>(RefChain.Nstrings)), Nraptot(0), Ix2_infty(Vect<DP>(RefChain.Nstrings)), Ix2_max(Vect<int>(RefChain.Nstrings)),
95
+      id (id_ref)
96
+  {
97
+    // Build Nrapidities vector from id_ref
98
+
99
+    long long int factor = pow_ulli (10LL, 2* RefChain.Nstrings + 1);
100
+    long long int id_eff = id_ref;
101
+    for (int i = 0; i < RefChain.Nstrings - 1; ++i) {
102
+      Nrap[RefChain.Nstrings - 1 - i] = id_eff/factor;
103
+      id_eff -= factor * Nrap[RefChain.Nstrings - 1 - i];
104
+      factor /= 100LL;
105
+    }
106
+    Nrap[0] = id_eff;
107
+
108
+    //id = id_ref;
109
+
110
+    //cout << "In Base constructor:  id_ref = " << id_ref << " and Nrapidities = " << Nrap << endl;
111
+    
112
+    // Check consistency of Nrapidities vector with RefChain
113
+
114
+    //if (RefChain.Nstrings != Nrap.size()) JSCerror("Incompatible Nrapidities vector used in Base constructor.");
115
+    
116
+    int Mcheck = 0;
117
+    for (int i = 0; i < RefChain.Nstrings; ++i) Mcheck += RefChain.Str_L[i] * Nrap[i];
118
+    Charge = Mcheck;
119
+    
120
+    Nraptot = 0;
121
+    for (int i = 0; i < RefChain.Nstrings; ++i) Nraptot += Nrap[i];
122
+    
123
+    // Now compute the Ix2_infty numbers
124
+
125
+    (*this).Compute_Ix2_limits(RefChain);
126
+  }
127
+
128
+
129
+  Base& Base::operator= (const Base& RefBase)
130
+  {
131
+    if (this != & RefBase) {
132
+      Charge = RefBase.Charge;
133
+      Nrap = RefBase.Nrap;
134
+      Nraptot = RefBase.Nraptot;
135
+      Ix2_infty = RefBase.Ix2_infty;
136
+      Ix2_max = RefBase.Ix2_max;
137
+      id = RefBase.id;
138
+    }
139
+    return(*this);
140
+  }
141
+  
142
+  bool Base::operator== (const Base& RefBase)
143
+  {
144
+    bool answer = (Nrap == RefBase.Nrap);
145
+
146
+    return (answer);
147
+  }
148
+
149
+  bool Base::operator!= (const Base& RefBase)
150
+  {
151
+    bool answer = (Nrap != RefBase.Nrap);
152
+
153
+    return (answer);
154
+  }
155
+
156
+  void Base::Compute_Ix2_limits (const Heis_Chain& RefChain)
157
+  {
158
+
159
+    if ((RefChain.Delta > 0.0) && (RefChain.Delta < 1.0)) {
160
+
161
+      // Compute the Ix2_infty numbers
162
+    
163
+      DP sum1 = 0.0;
164
+      DP sum2 = 0.0;
165
+      
166
+      for (int j = 0; j < RefChain.Nstrings; ++j) {
167
+	
168
+	sum1 = 0.0;
169
+	
170
+	for (int k = 0; k < RefChain.Nstrings; ++k) {
171
+	  
172
+	  sum2 = 0.0;
173
+	  
174
+	  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]) 
175
+										  - 0.5 * fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) * RefChain.anis));
176
+	  sum2 += 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k]) 
177
+				 - 0.5 * (RefChain.Str_L[j] + RefChain.Str_L[k]) * RefChain.anis));
178
+	  
179
+	  for (int a = 1; a < JSC::min(RefChain.Str_L[j], RefChain.Str_L[k]); ++a)
180
+	    sum2 += 2.0 * 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j] * RefChain.par[k]) 
181
+					 - 0.5 * (fabs(RefChain.Str_L[j] - RefChain.Str_L[k]) + 2.0*a) * RefChain.anis));
182
+	  
183
+	  sum1 += (Nrap[k] - ((j == k) ? 1 : 0)) * sum2;
184
+	}
185
+	
186
+	Ix2_infty[j] = (1.0/PI) * fabs(RefChain.Nsites * 2.0 * atan(tan(0.25 * PI * (1.0 + RefChain.par[j]) 
187
+								      - 0.5 * RefChain.Str_L[j] * RefChain.anis)) - sum1);
188
+	
189
+      }  // The Ix2_infty are now set.
190
+
191
+      // Now compute the Ix2_max limits
192
+      
193
+      for (int j = 0; j < RefChain.Nstrings; ++j) {
194
+	
195
+	Ix2_max[j] = int(floor(Ix2_infty[j]));  // sets basic integer
196
+
197
+	// Reject formally infinite rapidities (i.e. if Delta is root of unity)
198
+
199
+	//cout << "Ix2_infty - Ix2_max = " << Ix2_infty[j] - Ix2_max[j] << endl;
200
+	//if (Ix2_infty[j] == Ix2_max[j]) {
201
+	//Ix2_max[j] -= 2;
202
+	//}
203
+	// If Nrap is even, Ix2_max must be odd.  If odd, then even.
204
+
205
+	if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1;
206
+
207
+	while (Ix2_max[j] > RefChain.Nsites) {
208
+	  Ix2_max[j] -= 2;  
209
+	}
210
+      }
211
+    } // if XXZ gapless
212
+
213
+    else if (RefChain.Delta == 1.0) {
214
+
215
+      // Compute the Ix2_infty numbers
216
+    
217
+      int sum1 = 0;
218
+      
219
+      for (int j = 0; j < RefChain.Nstrings; ++j) {
220
+	
221
+	sum1 = 0;
222
+	
223
+	for (int k = 0; k < RefChain.Nstrings; ++k) {
224
+	  
225
+	  sum1 += Nrap[k] * (2 * JSC::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0));
226
+	}
227
+	
228
+	//Ix2_infty[j] = (RefChain.Nsites - 1.0 + 2.0 * RefChain.Str_L[j] - sum1);
229
+	Ix2_infty[j] = (RefChain.Nsites + 1.0 - sum1); // to get counting right...
230
+	
231
+      }  // The Ix2_infty are now set.
232
+      
233
+      // Now compute the Ix2_max limits
234
+      
235
+      for (int j = 0; j < RefChain.Nstrings; ++j) {
236
+
237
+	Ix2_max[j] = int(floor(Ix2_infty[j]));  // sets basic integer
238
+
239
+	// Give the correct parity to Ix2_max
240
+	
241
+	// If Nrap is even, Ix2_max must be odd.  If odd, then even.
242
+
243
+	if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1;
244
+
245
+	// If Ix2_max equals Ix2_infty, we reduce it by 2:
246
+	
247
+	if (Ix2_max[j] == int(Ix2_infty[j])) Ix2_max[j] -= 2;
248
+	
249
+	while (Ix2_max[j] > RefChain.Nsites) {
250
+	  Ix2_max[j] -= 2;  
251
+	}
252
+      }
253
+
254
+    } // if XXX AFM
255
+
256
+    else if (RefChain.Delta > 1.0) {
257
+
258
+      // Compute the Ix2_infty numbers
259
+      
260
+      int sum1 = 0;
261
+      
262
+      for (int j = 0; j < RefChain.Nstrings; ++j) {
263
+	
264
+	sum1 = 0;
265
+	
266
+	for (int k = 0; k < RefChain.Nstrings; ++k) {
267
+	  
268
+	  sum1 += Nrap[k] * (2 * JSC::min(RefChain.Str_L[j], RefChain.Str_L[k]) - ((j == k) ? 1 : 0));
269
+	}
270
+	
271
+	Ix2_infty[j] = (RefChain.Nsites - 1 + 2 * RefChain.Str_L[j] - sum1);
272
+	
273
+      }  // The Ix2_infty are now set.
274
+      
275
+      // Now compute the Ix2_max limits
276
+      
277
+      for (int j = 0; j < RefChain.Nstrings; ++j) {
278
+	
279
+	Ix2_max[j] = int(floor(Ix2_infty[j]));  // sets basic integer
280
+
281
+	// Give the correct parity to Ix2_max
282
+	
283
+	// If Nrap is even, Ix2_max must be odd.  If odd, then even.
284
+
285
+	if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1;
286
+	
287
+	// If Ix2_max equals Ix2_infty, we reduce it by 2:
288
+
289
+	//if (Ix2_max[j] == Ix2_infty[j]) Ix2_max[j] -= 2;
290
+
291
+	while (Ix2_max[j] > RefChain.Nsites) {
292
+	  Ix2_max[j] -= 2;  
293
+	}
294
+
295
+	// Fudge, for strings:
296
+	//if (RefChain.Str_L[j] >= 1) Ix2_max[j] += 2;
297
+	//Ix2_max[j] += 2;
298
+      }
299
+
300
+    } // if XXZ_gpd
301
+
302
+  }
303
+
304
+
305
+
306
+
307
+} // namespace JSC

+ 29
- 0
src/BETHE/Bethe_State.cc View File

@@ -0,0 +1,29 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  src/BETHE/Bethe_State.cc
10
+
11
+Purpose:  defines functions in Bethe_State class,
12
+          providing a unified object for eigenstates of all
13
+          Bethe Ansatz integrable models.
14
+
15
+
16
+
17
+
18
+***********************************************************/
19
+
20
+#include "JSC.h"
21
+
22
+using namespace std;
23
+
24
+namespace JSC {
25
+
26
+  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) :
27
+    base_id(base_id_ref), type_id(type_id_ref), id(id_ref), maxid(maxid_ref) {}
28
+
29
+} // namespace JSC

+ 277
- 0
src/BETHE/Offsets.cc View File

@@ -0,0 +1,277 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c) 2006-9.
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  src/BETHE/Offsets.cc
10
+
11
+Purpose:  defines functions in Offsets class.
12
+          
13
+
14
+Last modified:  19/10/2009
15
+
16
+***********************************************************/
17
+
18
+#include "JSC.h"
19
+
20
+using namespace std;
21
+
22
+namespace JSC {
23
+
24
+  //  Function definitions:  class Offsets
25
+
26
+  Offsets::Offsets () : base(), Tableau(Vect<Young_Tableau>()), type_id(0LL), id(0LL), maxid(0LL) {};
27
+
28
+  Offsets::Offsets (const Offsets& RefOffset) // copy constructor
29
+    : base(RefOffset.base), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)), type_id(RefOffset.type_id), id(RefOffset.id), maxid(RefOffset.maxid)
30
+  {
31
+    for (int i = 0; i < 2 * base.Nrap.size() + 2; ++i) Tableau[i] = RefOffset.Tableau[i];
32
+  }
33
+
34
+  Offsets::Offsets (const Heis_Base& RefBase, long long int req_type_id) 
35
+  // sets all tableaux to empty ones, with nparticles(req_type_id) at each level
36
+  {
37
+    // Build nparticles vector from req_type_id
38
+
39
+    Vect<int> nparticles(0, 2* RefBase.Nrap.size() + 2);
40
+    long long int factor = pow_ulli (10LL, nparticles.size() - 1);
41
+    long long int id_eff = req_type_id;
42
+    for (int i = 0; i < nparticles.size(); ++i) {
43
+      nparticles[nparticles.size() - 1 - i] = id_eff/factor;
44
+      id_eff -= factor * nparticles[nparticles.size() - 1 - i];
45
+      factor /= 10LL;
46
+    }
47
+
48
+    // Check if we've got the right vector...
49
+    long long int idcheck = Offsets_type_id (nparticles);
50
+    if (idcheck != req_type_id) JSCerror("idcheck != req_type_id in Offsets constructor.");
51
+
52
+    (*this) = Offsets(RefBase, nparticles);    
53
+  }
54
+
55
+  Offsets::Offsets (const Heis_Base& RefBase, Vect<int> nparticles) // sets all tableaux to empty ones, with nparticles at each level
56
+    : base(RefBase), Tableau(Vect<Young_Tableau> (2 * base.Nrap.size() + 2)), type_id(Offsets_type_id (nparticles)), id(0LL), maxid(0LL)
57
+  {
58
+
59
+    // Checks on nparticles vector:
60
+
61
+    if (nparticles.size() != 2 * base.Nrap.size() + 2) JSCerror("Wrong nparticles.size in Offsets constructor.");
62
+    
63
+    //if (base.Nrap[0] != (nparticles[3] + nparticles[2] + base.Mdown - nparticles[0] - nparticles[1])) JSCerror("Wrong Nrap[0] in Offsets constructor.");
64
+    if (nparticles[3] + nparticles[2] != nparticles[0] + nparticles[1]) {
65
+      cout << nparticles[0] << "\t" << nparticles[1] << "\t" << nparticles[2] << "\t" << nparticles[3] << endl;
66
+      JSCerror("Wrong Npar[0-3] in Offsets constructor.");
67
+    }
68
+
69
+    for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level) 
70
+      if (base.Nrap[base_level] != nparticles[2*base_level + 2] + nparticles[2*base_level + 3]) {
71
+	cout << base_level << "\t" << base.Nrap[base_level] << "\t" << nparticles[2*base_level + 2] << "\t" <<  nparticles[2*base_level + 3] << endl;
72
+	JSCerror("Wrong Nrap[] in Offsets constructor.");
73
+      }
74
+
75
+    // nparticles[0,1]:  number of holes on R and L side in GS interval
76
+    if (nparticles[0] > (base.Nrap[0] + 1)/2) JSCerror("nparticles[0] too large in Offsets constructor.");
77
+    if (nparticles[1] > base.Nrap[0]/2) JSCerror("nparticles[1] too large in Offsets constructor.");
78
+
79
+    // nparticles[2,3]:  number of particles of type 0 on R and L side out of GS interval
80
+    if (nparticles[2] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) JSCerror("nparticles[2] too large in Offsets constructor.");
81
+    if (nparticles[3] > (base.Ix2_max[0] - base.Nrap[0] + 1)/2) JSCerror("nparticles[3] too large in Offsets constructor.");
82
+
83
+    for (int base_level = 1; base_level < base.Nrap.size(); ++ base_level)
84
+      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)
85
+	  //|| (nparticles[2*base_level + 3] > 0 && nparticles[2*base_level + 3] > (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2)) {
86
+	  || (nparticles[2*base_level + 3] > 0 
87
+	      && nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)) {
88
+	cout << base_level << "\t" << nparticles[2*base_level + 2] << "\t" << (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2
89
+	     << "\t" << nparticles[2*base_level + 3] << "\t" << (base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2 
90
+	     << "\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)
91
+	  //<< "\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)
92
+	     << "\t" << (nparticles[2*base_level + 3] > 0) << "\t" 
93
+	     << (nparticles[2*base_level + 3] > base.Ix2_max[base_level] + 1 - (base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2) + 2)/2)
94
+	     << endl;
95
+	JSCerror("nparticles too large in Offsets constructor.");
96
+      }
97
+    
98
+    // Check sum of rapidities
99
+
100
+    // Holes in GS interval
101
+    Tableau[0] = Young_Tableau(nparticles[0], (base.Nrap[0] + 1)/2 - nparticles[0]);
102
+    Tableau[1] = Young_Tableau(nparticles[1], base.Nrap[0]/2 - nparticles[1], Tableau[0]);
103
+
104
+    // Particles of type 0 out of GS interval
105
+    Tableau[2] = Young_Tableau(nparticles[2], (base.Ix2_max[0] - base.Nrap[0] + 1)/2 - nparticles[2], Tableau[0]);
106
+    Tableau[3] = Young_Tableau(nparticles[3], (base.Ix2_max[0] - base.Nrap[0] + 1)/2 - nparticles[3], Tableau[2]);
107
+    
108
+    // Tableaux of index i = 2,...:  data about string type i/2-1.
109
+    for (int base_level = 1; base_level < base.Nrap.size(); ++base_level) {
110
+      Tableau[2*base_level + 2] = Young_Tableau(nparticles[2*base_level + 2], 
111
+						//(base.Ix2_max[base_level] - ((base.Nrap[base_level]) % 2) + 2)/2 - nparticles[2*base_level + 2], Tableau[2]);
112
+						//(base.Ix2_max[base_level] - base.Nrap[base_level] % 2 + 2)/2 - nparticles[2*base_level + 2], Tableau[2]);
113
+						(base.Ix2_max[base_level] - ((base.Nrap[base_level] + 1) % 2))/2 + 1 - nparticles[2*base_level + 2], Tableau[2]);
114
+      Tableau[2*base_level + 3] = Young_Tableau(nparticles[2*base_level + 3], 
115
+						//(base.Ix2_max[base_level] - base.Nrap[base_level] % 2)/2 - nparticles[2*base_level + 3], Tableau[3]);
116
+						(base.Ix2_max[base_level] - (base.Nrap[base_level] % 2) - 1)/2 + 1 - nparticles[2*base_level + 3], Tableau[3]);
117
+    }
118
+
119
+    maxid = 1LL;
120
+    //id = Tableau[0].id;
121
+    for (int i = 0; i < nparticles.size(); ++i) {
122
+      maxid *= Tableau[i].maxid + 1LL;
123
+      //id += maxid + Tableau[i].id;
124
+    }
125
+    maxid -= 1LL;
126
+
127
+  }
128
+
129
+  Offsets& Offsets::operator= (const Offsets& RefOffset)
130
+  {
131
+    if (this != &RefOffset) {
132
+      base = RefOffset.base;
133
+      Tableau = RefOffset.Tableau;
134
+      type_id = RefOffset.type_id;
135
+      id = RefOffset.id;
136
+      maxid = RefOffset.maxid;
137
+    }
138
+    return(*this);
139
+  }
140
+
141
+  bool Offsets::operator<= (const Offsets& RefOffsets)
142
+  {
143
+    // Check whether all nonzero tableau row lengths in RefOffsets
144
+    // are <= than those in *this
145
+
146
+    bool answer = true;
147
+    for (int level = 0; level < 4; ++level) { // check fundamental level only
148
+      //for (int level = 0; level < 2 * base.Nrap.size() + 2; ++level) {
149
+      // First check whether all rows which exist in both tableaux satisfy rule:
150
+      for (int tableau_level = 0; tableau_level < JSC::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
151
+	if (Tableau[level].Row_L[tableau_level] > RefOffsets.Tableau[level].Row_L[tableau_level]) 
152
+	  answer = false;
153
+      // Now check whether there exist extra rows violating rule:
154
+      for (int tableau_level = JSC::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); tableau_level < Tableau[level].Nrows; ++tableau_level)
155
+	if (Tableau[level].Row_L[tableau_level] > 0) answer = false;
156
+    }
157
+
158
+    return(answer);
159
+  }
160
+
161
+  bool Offsets::operator>= (const Offsets& RefOffsets)
162
+  {
163
+    // Check whether all nonzero tableau row lengths in RefOffsets
164
+    // are >= than those in *this
165
+
166
+    bool answer = true;
167
+    for (int level = 0; level < 4; ++level) { // check fundamental level only
168
+      //for (int level = 0; level < 2 * base.Nrap.size() + 2; ++level) {
169
+      // First check whether all rows which exist in both tableaux satisfy rule:
170
+      for (int tableau_level = 0; tableau_level < JSC::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); ++tableau_level)
171
+	if (Tableau[level].Row_L[tableau_level] < RefOffsets.Tableau[level].Row_L[tableau_level]) 
172
+	  answer = false;
173
+      // Now check whether there exist extra rows violating rule:
174
+      for (int tableau_level = JSC::min(Tableau[level].Nrows, RefOffsets.Tableau[level].Nrows); tableau_level < RefOffsets.Tableau[level].Nrows; ++tableau_level)
175
+	if (RefOffsets.Tableau[level].Row_L[tableau_level] > 0) answer = false;
176
+    }
177
+
178
+    return(answer);
179
+  }
180
+
181
+  void Offsets::Compute_type_id ()
182
+  {
183
+    type_id = 0LL;
184
+
185
+    for (int i = 0; i < 2*base.Nrap.size() + 2; ++i) {
186
+      Tableau[i].Compute_id();
187
+      type_id += Tableau[i].Nrows * pow_ulli(10LL, i);
188
+    }
189
+  }
190
+
191
+  void Offsets::Set_to_id (long long int idnr)
192
+  {
193
+    // The idnr of the Offset is given by 
194
+    // sub_id[0] + (total number of tableaux of type 0) * (sub_id[1] + (total number of tableaux of type 1) * (sub_id[2] + ...
195
+    // + total number of tableaux of type (2*base.Nrap.size()) * sub_id[2*base.Nrap.size() + 1]
196
+
197
+    if (idnr > maxid) {
198
+      cout << idnr << "\t" << maxid << endl;
199
+      JSCerror("idnr too large in offsets.Set_to_id.");
200
+    }
201
+
202
+    id = idnr;
203
+
204
+    Vect<long long int> sub_id(0LL, 2*base.Nrap.size() + 2);
205
+
206
+    long long int idnr_eff = idnr;
207
+    long long int temp_prod = 1LL;
208
+
209
+    Vect<long long int> result_choose(2*base.Nrap.size() + 2);
210
+
211
+    for (int i = 0; i <= 2*base.Nrap.size(); ++i) {
212
+      //result_choose[i] = choose_lli(Tableau[i].Nrows + Tableau[i].Ncols, Tableau[i].Nrows);
213
+      result_choose[i] = Tableau[i].maxid + 1LL;
214
+      temp_prod *= result_choose[i];
215
+    }
216
+
217
+    for (int i = 2*base.Nrap.size() + 1; i > 0; --i) {
218
+      sub_id[i] = idnr_eff/temp_prod;
219
+      idnr_eff -= sub_id[i] * temp_prod;
220
+      temp_prod /= result_choose[i-1];
221
+    }
222
+    sub_id[0] = idnr_eff; // what's left goes to the bottom...
223
+
224
+    for (int i = 0; i <= 2*base.Nrap.size() + 1; ++i) {
225
+      //cout << "level = " << i << " Tableau.id = " << sub_id[i] << endl;
226
+      if ((Tableau[i].Nrows * Tableau[i].Ncols == 0) && (sub_id[i] != 0)) JSCerror("index too large in offset.Set_to_id.");
227
+      if (Tableau[i].id != sub_id[i]) Tableau[i].Set_to_id(sub_id[i]);
228
+    }
229
+
230
+    Compute_type_id ();
231
+
232
+    return;
233
+  }
234
+
235
+  void Offsets::Compute_id ()
236
+  {
237
+    long long int prod_maxid = 1LL;
238
+    
239
+    id = 0LL;
240
+
241
+    for (int i = 0; i < 2*base.Nrap.size() + 2; ++i) {
242
+      Tableau[i].Compute_id();
243
+      id += Tableau[i].id * prod_maxid;
244
+      prod_maxid *= Tableau[i].maxid + 1LL;
245
+    }
246
+  }
247
+
248
+  Vect<long long int> Offsets::Descendents (bool fixed_iK)
249
+  {
250
+    // From a given vector of Young tableaux specifying a particular eigenstate,
251
+    // this function provides the full set of descendents (either at the same momentum if
252
+    // fixed_iK == true, or not) by returning a vector of all descendent id's (leaving the
253
+    // base and type invariant), which can then be used for further calculations.
254
+    
255
+    // This set of descendents is meant to be used when calculating either partition functions
256
+    // or zero-temperature correlation functions.
257
+    
258
+    // IMPORTANT ASSUMPTIONS:  
259
+    // - all even sectors consistently increase/decrease momentum for increasing tableau row length
260
+    // - all odd  sectors consistently decrease/increase momentum for increasing tableau row length
261
+    
262
+    // FOR FIXED MOMENTUM:
263
+    // all tableau levels `above' the lowest occupied one are descended as for fixed_iK == false,
264
+    // and the lowest sector's highest tableau level's row length is modified (increased or decreased by one
265
+    // unit if possible) such that the iK of Tableau_desc == iK of Tableau_ref.
266
+    // The logic behind this is that for a state with nexc excitations, we let run nexc - 1 of the
267
+    // excitations, and the lowest one is fixed in place by the momentum constraint, if possible.
268
+
269
+    Vect<Young_Tableau> Tableau_ref = (*this).Tableau;
270
+    Vect<Young_Tableau> Tableau_desc = Tableau_ref;
271
+
272
+    
273
+  }
274
+
275
+
276
+
277
+} // namespace JSC

+ 89
- 0
src/COMBI/Combinatorics.cc View File

@@ -0,0 +1,89 @@
1
+/****************************************************************
2
+
3
+This software is part of J.-S. Caux's C++ library.
4
+
5
+Copyright (c) 2006.
6
+
7
+-----------------------------------------------------------
8
+
9
+Combinatorics.cc
10
+
11
+Defines all class related to combinatorics.
12
+
13
+LAST MODIFIED:  04/09/06
14
+
15
+******************************************************************/
16
+
17
+#include "JSC.h"
18
+
19
+using namespace std;
20
+
21
+namespace JSC {
22
+
23
+  Choose_Table::Choose_Table () 
24
+    : Npower(0ULL), Npowerp1(1ULL), table(new unsigned long long int[1])
25
+  {
26
+    table[0] = 1ULL;
27
+  }
28
+
29
+  Choose_Table::Choose_Table (int Npower_ref)
30
+    : Npower(Npower_ref), Npowerp1(Npower_ref + 1ULL)
31
+  {
32
+    dim = Npowerp1 * Npowerp1;
33
+
34
+    // We can only go up to ULL_MAX:
35
+    if (log(DP(ULONG_LONG_MAX)) < DP(Npowerp1) * log(2.0))
36
+      JSCerror("Choose_Table:  too large to contruct.");
37
+
38
+    table = new unsigned long long int[dim];
39
+
40
+    (*this).Fill_table();
41
+  }
42
+
43
+  void Choose_Table::Fill_table()
44
+  {
45
+    table[0] = 1ULL;
46
+    int n,m;
47
+    for (n = 0; n <= Npower; ++n) {
48
+      table[Npowerp1 * n] = 1ULL;
49
+      for (m = 1; m < n; ++m) {
50
+	table[Npowerp1 * n + m] = table[Npowerp1 * (n-1) + m - 1] + table[Npowerp1 * (n-1) + m];
51
+      }
52
+      table[Npowerp1 * n + n] = 1ULL;
53
+      for (m = n+1; m <= Npower; ++m)
54
+	table[Npowerp1 * n + m] = 0ULL;
55
+    }
56
+  }
57
+
58
+  int Choose_Table::power()
59
+  {
60
+    return(Npower);
61
+  }
62
+
63
+  unsigned long long int Choose_Table::choose(int N, int M)
64
+  {
65
+    if (N < 0 || N > Npower) JSCerror("N out of bounds in choose(N,M).");
66
+    if (M < 0 || M > Npower) JSCerror("M out of bounds in choose(N,M).");
67
+
68
+    return(table[Npowerp1 * N + M]);
69
+  }
70
+
71
+  std::ostream& operator<< (std::ostream& s, Choose_Table& Ref_table)
72
+    {
73
+      s << endl;
74
+      for (int n = 0; n <= Ref_table.power(); ++n) {
75
+	for (int m = 0; m <= Ref_table.power(); ++m)
76
+	  s << Ref_table.choose(n, m) << " ";
77
+	s << endl;
78
+      }
79
+      s << endl;
80
+      return(s);
81
+    }
82
+
83
+  Choose_Table::~Choose_Table()
84
+  {
85
+    delete[] table;
86
+  }
87
+
88
+
89
+} // namespace JSC

+ 43
- 0
src/EXECS/2CBG_ThLim.cc View File

@@ -0,0 +1,43 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  2CBG_ThLim.cc
10
+
11
+Purpose:  solves the TBA equations for the 2-component Bose gas
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+using namespace JSC;
20
+
21
+int main(int argc, const char* argv[])
22
+{
23
+
24
+  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).");
25
+
26
+  DP c_int = atof(argv[1]);
27
+  DP mu = atof(argv[2]);
28
+  DP Omega = atof(argv[3]);
29
+  DP kBT = atof(argv[4]);
30
+  int Max_Secs = 60 * atoi(argv[5]);
31
+  bool Save_data = bool(atoi(argv[6]));
32
+
33
+  if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
34
+  if (Omega <= 0.0) JSCerror("Give a strictly positive Omega, otherwise the algorithm cannot converge.");
35
+  if (kBT <= 0.0) JSCerror("Negative T ?  You must be a string theorist.");
36
+  if (Max_Secs < 10) JSCerror("Give more time.");
37
+
38
+  //cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
39
+
40
+  Solve_2CBG_TBAE_via_refinements (c_int, mu, Omega, kBT, Max_Secs, Save_data);
41
+
42
+  return(0);
43
+}

+ 84
- 0
src/EXECS/Analyze_RAW_File.cc View File

@@ -0,0 +1,84 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Analyze_RAW_File.cc
10
+
11
+Purpose:  give some statistics for the matrix element distribution in a raw file.
12
+          
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 4) { 
24
+    cout << "Argument needed: rawfile, iKmin, iKmax." << endl;
25
+    JSCerror("");
26
+  }
27
+
28
+  const char* rawfilename = argv[1];
29
+  int iKmin = atoi(argv[2]);
30
+  int iKmax = atoi(argv[3]);
31
+
32
+  ifstream RAW_infile;
33
+  RAW_infile.open(rawfilename);
34
+  if (RAW_infile.fail()) {
35
+    cout << rawfilename << endl;
36
+    JSCerror("Could not open RAW_infile... "); 
37
+  }
38
+
39
+  DP omega;
40
+  int iK;
41
+  DP FF;
42
+  //int conv;
43
+  DP dev;
44
+  string label;
45
+
46
+  DP sumFFsq = 0.0;
47
+  DP sumFF4 = 0.0;
48
+  DP sumFFsqlnFFsq = 0.0;
49
+
50
+  Vect<int> nFFatK (0, iKmax - iKmin + 1);
51
+  Vect<DP> sumFFsqatK (0.0, iKmax - iKmin + 1);
52
+  Vect<DP> sumFF4atK (0.0, iKmax - iKmin + 1);
53
+  Vect<DP> sumFFsqlnFFsqatK (0.0, iKmax - iKmin + 1);
54
+
55
+  int nread = 0;
56
+
57
+  while (RAW_infile.peek() != EOF) {
58
+    RAW_infile >> omega >> iK >> FF >> dev >> label;
59
+
60
+    nread++;
61
+    sumFFsq += FF*FF;
62
+    sumFF4 += FF*FF*FF*FF;
63
+    sumFFsqlnFFsq += FF*FF * log(FF*FF);
64
+
65
+    if (iK >= iKmin && iK <= iKmax) {
66
+      nFFatK[iK-iKmin] += 1;
67
+      sumFFsqatK[iK - iKmin] += FF*FF;
68
+      sumFF4atK[iK - iKmin] += FF*FF*FF*FF;
69
+      sumFFsqlnFFsqatK[iK - iKmin] += FF*FF * log(FF*FF);
70
+    }
71
+  }
72
+
73
+  RAW_infile.close();
74
+
75
+  cout << "Inverse participation ratio: \t" << sumFF4/(sumFFsq*sumFFsq) << endl; 
76
+  // Entropy is -sum (FFsq/sumFFsq) * ln(FFsq/sumFFsq) = sum (FFsq lnFFsq - FFsq ln sumFFsq)/sumFFsq
77
+  cout << "Entropy: \t" << -(sumFFsqlnFFsq - sumFFsq * log(sumFFsq))/sumFFsq << endl;
78
+
79
+  cout << "iK\tnFFatK\tIPRatiK\tentropyatiK:" << endl;
80
+  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;
81
+
82
+
83
+  return(0);
84
+}

+ 147
- 0
src/EXECS/Check_RAW_File.cc View File

@@ -0,0 +1,147 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Check_RAW_File.cc
10
+
11
+Purpose:  from a .raw_srt file, check that nonzero momentum states 
12
+          appear (only) twice, and zero momentum ones (only) once.
13
+          
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+using namespace JSC;
20
+
21
+
22
+int main(int argc, char* argv[]) 
23
+{
24
+  if (argc != 7) { // print out some instructions
25
+    cout << "Usage of Check_RAW_File executable:  provide the following arguments:" << endl;
26
+    cout << "(sorted!) raw file name, iKmin, iKmax, sympoint, FFmin, check_option." << endl;
27
+    cout << "Check option:  0 == check for missing states,  1 == check for multiply-appearing states." << endl;
28
+  }
29
+
30
+  char* rawfilename = argv[1];
31
+  int iKmin = atoi(argv[2]);
32
+  int iKmax = atoi(argv[3]); 
33
+  int sympoint = atoi(argv[4]);
34
+  DP FFmin = atof(argv[5]);
35
+  int check_option = atoi(argv[6]);
36
+
37
+    ifstream RAW_infile;
38
+    RAW_infile.open(rawfilename);
39
+    if (RAW_infile.fail()) {
40
+      cout << rawfilename << endl;
41
+      JSCerror("Could not open sorted RAW_infile... "); 
42
+    }
43
+
44
+    DP omega_next, omega, omega_prev;
45
+    int iK_next, iK, iK_prev;
46
+    DP FF_next, FF, FF_prev;
47
+    //int conv_next, conv, conv_prev;
48
+    DP dev_next, dev, dev_prev;
49
+    string label_next, label, label_prev;
50
+
51
+    if (check_option > 1) {
52
+      FF = 0.0;
53
+      FF_prev = 0.0;
54
+      FF_next = 0.0;
55
+      FFmin = -1.0;
56
+    }
57
+
58
+    //RAW_infile >> omega >> iK >> FF >> conv >> label;
59
+    RAW_infile >> omega >> iK;
60
+    if (check_option <= 1) RAW_infile >> FF;
61
+    RAW_infile >> dev;
62
+    RAW_infile >> label;
63
+    //RAW_infile >> omega_next >> iK_next >> FF_next >> conv_next >> label_next;
64
+    RAW_infile >> omega_next >> iK_next;
65
+    if (check_option <= 1) RAW_infile >> FF_next;
66
+    RAW_infile >> dev_next;
67
+    RAW_infile >> label_next;
68
+
69
+    int line = 1;
70
+
71
+    char a;
72
+
73
+
74
+    while (fabs(FF) > FFmin && RAW_infile.peek() != EOF) {
75
+
76
+      //omega_prev = omega; iK_prev = iK; FF_prev = FF; conv_prev = conv; label_prev = label;
77
+      omega_prev = omega; iK_prev = iK; FF_prev = FF; dev_prev = dev; label_prev = label;
78
+      //omega = omega_next; iK = iK_next; FF = FF_next; conv = conv_next; label = label_next;
79
+      omega = omega_next; iK = iK_next; FF = FF_next; dev = dev_next; label = label_next;
80
+      //RAW_infile >> omega_next >> iK_next >> FF_next >> conv_next >> label_next;
81
+      RAW_infile >> omega_next >> iK_next;
82
+      if (check_option <= 1) RAW_infile >> FF_next; // for non-Z checks
83
+      RAW_infile >> dev_next;
84
+      RAW_infile >> label_next;
85
+      //cout << "checking line " << line << endl;
86
+      //cout << omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << label_prev << endl
87
+      //   << omega << "\t" << iK << "\t" << FF << "\t" << label << endl
88
+      //   << omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << label_next << endl;
89
+      line++;
90
+
91
+      if (label.compare(label_next) == 0) 
92
+	cout << "Identical labels around line " << line << ": " << endl
93
+	     << omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl;
94
+      
95
+      if (check_option == 0 && iK != 0 && iK != sympoint && iK >= iKmin && iK <= iKmax 
96
+	  && fabs((FF - FF_prev)/(FF + FF_prev)) > 1.0e-6 && fabs((FF - FF_next)/(FF + FF_next)) > 1.0e-6) {
97
+	
98
+	cout << "State missing around line " << line << ": " << endl 
99
+	  //<< omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << conv_prev << "\t" << label_prev << endl
100
+	     << omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << dev_prev << "\t" << label_prev << endl
101
+	  //<< omega << "\t" << iK << "\t" << FF << "\t" << conv << "\t" << label << endl
102
+	     << omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl
103
+	  //<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << conv_next << "\t" << label_next << endl;
104
+	     << omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << dev_next << "\t" << label_next << endl;
105
+
106
+	cin >> a;
107
+	//break;
108
+      }
109
+
110
+      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) {
111
+
112
+	cout << "Triple state around line " << line << ": " << endl
113
+	  //<< omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << conv_prev << "\t" << label_prev << endl
114
+	     << omega_prev << "\t" << iK_prev << "\t" << FF_prev << "\t" << dev_prev << "\t" << label_prev << endl
115
+	  //<< omega << "\t" << iK << "\t" << FF << "\t" << conv << "\t" << label << endl
116
+	     << omega << "\t" << iK << "\t" << FF << "\t" << dev << "\t" << label << endl
117
+	  //<< omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << conv_next << "\t" << label_next << endl;
118
+	     << omega_next << "\t" << iK_next << "\t" << FF_next << "\t" << dev_next << "\t" << label_next << endl;
119
+	cin >> a;
120
+      }
121
+
122
+      if (check_option == 2 && iK != 0 && iK != sympoint && iK >= iKmin && iK <= iKmax 
123
+	  && fabs((omega - omega_prev)/(omega + omega_prev)) > 1.0e-6 && fabs((omega - omega_next)/(omega + omega_next)) > 1.0e-6) {
124
+	
125
+	cout << "State missing around line " << line << ": " << endl 
126
+	     << omega_prev << "\t" << iK_prev << "\t" << dev_prev << "\t" << label_prev << endl
127
+	     << omega << "\t" << iK << "\t" << dev << "\t" << label << endl
128
+	     << omega_next << "\t" << iK_next << "\t" << dev_next << "\t" << label_next << endl;
129
+
130
+	cin >> a;
131
+	//break;
132
+      }
133
+
134
+      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) {
135
+
136
+	cout << "Triple state around line " << line << ": " << endl
137
+	     << omega_prev << "\t" << iK_prev << "\t" << dev_prev << "\t" << label_prev << endl
138
+	     << omega << "\t" << iK << "\t" << dev << "\t" << label << endl
139
+	     << omega_next << "\t" << iK_next << "\t" << dev_next << "\t" << label_next << endl;
140
+	cin >> a;
141
+      }
142
+
143
+    }
144
+
145
+    return(0);
146
+}
147
+

+ 142
- 0
src/EXECS/Heis_DSF.cc View File

@@ -0,0 +1,142 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Heis_DSF.cc
10
+
11
+Purpose:  main function for ABACUS++ for Heisenberg spin-1/2 chain
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 8) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of Heis_DSF executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP Delta \t\t Value of the anisotropy:  use positive real values only" << endl;
31
+    cout << "int N \t\t\t Length (number of sites) of the system:  use positive even integer values only" << endl;
32
+    cout << "int M \t\t\t Number of down spins:  use positive integer values between 1 and N/2" << endl;
33
+    //cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  0 and N" << endl;
34
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
35
+    cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
36
+    cout << "bool refine \t\t Is this a refinement of a earlier calculations ?  (0 == false, 1 == true)" << endl;
37
+    cout << endl << "EXAMPLE: " << endl << endl;
38
+    cout << "Heis_DSF z 1.0 100 40 0 100 600 1.0 0" << endl << endl;
39
+  }
40
+
41
+  else if (argc == 8) { // !fixed_iK
42
+    int ctr = 1;
43
+    char whichDSF = *argv[ctr++];
44
+    DP Delta = atof(argv[ctr++]);
45
+    int N = atoi(argv[ctr++]);
46
+    int M = atoi(argv[ctr++]);
47
+    //int iKmin = atoi(argv[5]);
48
+    //int iKmax = atoi(argv[6]);
49
+    int Max_Secs = atoi(argv[ctr++]);
50
+    DP target_sumrule = atof(argv[ctr++]);
51
+    bool refine = (atoi(argv[ctr++]) == 1);
52
+
53
+    // We systematically scan over all momentum integers (to avoid problems with Brillouin folding
54
+    int iKmin = -1000*N;
55
+    int iKmax = 1000*N;
56
+    //Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine, 0, 1);
57
+    Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine);
58
+  }
59
+
60
+
61
+
62
+  // The argument given is the name of the standard args_Heis_DSF arguments file
63
+
64
+  /*
65
+  if (argc == 2) { // Used an input file to provide the arguments
66
+
67
+    if (strcmp(argv[1],"help") == 0) { // Output some instructions
68
+      cout << "Usage of Heis_DSF executable: " << endl;
69
+      cout << endl << "Provide arguments by either using one of the three following options:" << endl << endl;
70
+      cout << "1) via an argument file (see the template `args_Heis_DSF' in directory src/EXECS/), for example" << endl << endl;
71
+      cout << "Heis_DSF args_Heis_DSF" << endl << endl;
72
+      cout << "2) with arguments (for general momenta scan) whichDSF Delta N M iKmin iKmax Max_Secs refine, for example" << endl << endl;
73
+      cout << "Heis_DSF z 0.9 100 40 0 50 600 0" << endl << endl;
74
+      cout << "3) with arguments (for general momenta scan) whichDSF Delta N M iKneeded Max_Secs refine, for example" << endl << endl;
75
+      cout << "Heis_DSF z 0.9 100 40 20 600 0" << endl << endl;
76
+    }
77
+
78
+    else { // read argument file
79
+
80
+      ifstream argsfile;
81
+      argsfile.open(argv[1]);
82
+      if (argsfile.fail()) {
83
+	cout << argv[1] << endl;
84
+	JSCerror("Could not open arguments file.");
85
+      }
86
+
87
+    char junk[256];
88
+    while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
89
+    char whichDSF;  argsfile >> whichDSF;
90
+    while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
91
+    DP Delta;  argsfile >> Delta;
92
+    while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
93
+    int N; argsfile >> N;
94
+    while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
95
+    int M; argsfile >> M;
96
+    while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
97
+    //bool fixed_iK; argsfile >> fixed_iK;
98
+    //while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
99
+    //int iKneeded; argsfile >> iKneeded;
100
+    int iKmin, iKmax;  argsfile >> iKmin >> iKmax;
101
+    while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
102
+    int Max_Secs; argsfile >> Max_Secs;
103
+    while (argsfile.peek() == '#' || argsfile.peek() == '\t' || argsfile.peek() == ' ' || argsfile.peek() == '\n') argsfile.getline(junk, 256);
104
+    bool refine;  argsfile >> refine;
105
+
106
+    Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, refine);
107
+    }
108
+  } // if (argc == 2)
109
+
110
+  else if (argc == 8) { // fixed_iK
111
+    char whichDSF = *argv[1];
112
+    DP Delta = atof(argv[2]);
113
+    int N = atoi(argv[3]);
114
+    int M = atoi(argv[4]);
115
+    int iKneeded = atoi(argv[5]);
116
+    int Max_Secs = atoi(argv[6]);
117
+    bool refine = (atoi(argv[7]) == 1);
118
+
119
+    //Scan_Heis (whichDSF, Delta, N, M, iKneeded, Max_Secs, refine);
120
+    Scan_Heis (whichDSF, Delta, N, M, iKneeded, iKneeded, Max_Secs, refine);
121
+  }
122
+
123
+  else if (argc == 9) { // !fixed_iK
124
+    char whichDSF = *argv[1];
125
+    DP Delta = atof(argv[2]);
126
+    int N = atoi(argv[3]);
127
+    int M = atoi(argv[4]);
128
+    int iKmin = atoi(argv[5]);
129
+    int iKmax = atoi(argv[6]);
130
+    int Max_Secs = atoi(argv[7]);
131
+    bool refine = (atoi(argv[8]) == 1);
132
+
133
+    //Scan_Heis (whichDSF, Delta, N, M, iKneeded, Max_Secs, refine);
134
+    Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, refine);
135
+  }
136
+
137
+  else JSCerror("Wrong number of arguments to Heis_DSF executable.");
138
+  */
139
+
140
+  return(0);
141
+}
142
+

+ 133
- 0
src/EXECS/Heis_DSF_GeneralState.cc View File

@@ -0,0 +1,133 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Heis_DSF_GeneralState.cc
10
+
11
+Purpose:  main function for ABACUS++ for Heisenberg spin-1/2 chain
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 9) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of Heis_DSF executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP Delta \t\t Value of the anisotropy:  use positive real values only" << endl;
31
+    cout << "int N \t\t\t Length (number of sites) of the system:  use positive even integer values only" << endl;
32
+    cout << "int M \t\t\t Number of down spins:  use positive integer values between 1 and N/2" << endl;
33
+    cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
34
+    //cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  0 and N" << endl;
35
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
36
+    cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
37
+    cout << "bool refine \t\t Is this a refinement of a earlier calculations ?  (0 == false, 1 == true)" << endl;
38
+    cout << endl << "EXAMPLE: " << endl << endl;
39
+  }
40
+
41
+  else if (argc == 9) { // !fixed_iK
42
+    int ctr = 1;
43
+    char whichDSF = *argv[ctr++];
44
+    DP Delta = atof(argv[ctr++]);
45
+    int N = atoi(argv[ctr++]);
46
+    int M = atoi(argv[ctr++]);
47
+    char* Ix2filenameprefix = argv[ctr++];
48
+    //int iKmin = atoi(argv[5]);
49
+    //int iKmax = atoi(argv[6]);
50
+    int Max_Secs = atoi(argv[ctr++]);
51
+    DP target_sumrule = atof(argv[ctr++]);
52
+    bool refine = (atoi(argv[ctr++]) == 1);
53
+
54
+    // We systematically scan over all momentum integers (to avoid problems with Brillouin folding
55
+    int iKmin = -1000*N;
56
+    int iKmax = 1000*N;
57
+
58
+    // Read the Ix2 from the file:
59
+    // Format is:
60
+    // base_level, Nrap[base_level], \endl Ix2[base_level], repeat for all occupied base_levels...
61
+    ifstream Ix2_input_file;
62
+    stringstream filenamestrstream;
63
+    filenamestrstream << Ix2filenameprefix;
64
+    string defaultScanStatename = filenamestrstream.str();
65
+    filenamestrstream << ".Ix2";
66
+    string filenamestr = filenamestrstream.str();
67
+    const char* filename_Cstr = filenamestr.c_str();
68
+    Ix2_input_file.open(filename_Cstr);
69
+    if (Ix2_input_file.fail()) {
70
+      cout << filename_Cstr << endl;
71
+      JSCerror("Could not open Ix2 input file in Heis_DSF_GeneralState");
72
+    }
73
+
74
+    Heis_Chain chain(1.0, Delta, 0.0, N);
75
+
76
+    Vect<int> Nrap_read (0, chain.Nstrings);
77
+    int level = 0;
78
+    Vect<Vect<int> > Ix2_read (chain.Nstrings);
79
+    do {
80
+      Ix2_input_file >> level;
81
+      Ix2_input_file >> Nrap_read[level];
82
+      Ix2_read[level] = Vect<int> (Nrap_read[level]);
83
+      for (int alpha = 0; alpha < Nrap_read[level]; ++alpha) Ix2_input_file >> Ix2_read[level][alpha];
84
+      //cout << "Read level = " << level << "\tNrap_read[level] = " << Nrap_read[level] << endl;
85
+      //cout << "\tIx2_read[level] = " << Ix2_read[level] << endl;
86
+    } while (Ix2_input_file.peek() != EOF);
87
+
88
+    // Construct the Averaging State:
89
+    Heis_Base base (chain, Nrap_read);
90
+
91
+    int paralevel = 0;
92
+    Vect<int> rank; // dummy
93
+    Vect<int> nr_processors; // dummy
94
+
95
+    if (Delta > 0.0 && Delta < 1.0) {
96
+      XXZ_Bethe_State AveragingState (chain, base);
97
+      for (int il = 0; il < chain.Nstrings; ++il) {
98
+	if (Nrap_read[il] > 0) for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
99
+      }
100
+      AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
101
+      AveragingState.Compute_All(true);
102
+
103
+      //cout << "AveragingState read from file: " << AveragingState << endl;
104
+      // Perform the scan:
105
+      Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
106
+    }
107
+    else if (Delta == 1.0) {
108
+      XXX_Bethe_State AveragingState (chain, base);
109
+      for (int il = 0; il < chain.Nstrings; ++il) {
110
+	for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
111
+      }
112
+      AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
113
+      AveragingState.Compute_All(true);
114
+      
115
+      // Perform the scan:
116
+      Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
117
+    }
118
+    else if (Delta > 1.0) {
119
+      XXZ_gpd_Bethe_State AveragingState (chain, base);
120
+      for (int il = 0; il < chain.Nstrings; ++il) {
121
+	for (int alpha = 0; alpha < Nrap_read[il]; ++alpha) AveragingState.Ix2[il][alpha] = Ix2_read[il][alpha];
122
+      }
123
+      AveragingState.Set_Label_from_Ix2(AveragingState.Ix2);
124
+      AveragingState.Compute_All(true);
125
+      
126
+      // Perform the scan:
127
+      Scan_Heis (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
128
+    }
129
+  }
130
+
131
+  return(0);
132
+}
133
+

+ 120
- 0
src/EXECS/Heis_DSF_par.cc View File

@@ -0,0 +1,120 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Heis_DSF_par.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+#include "mpi.h"
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP Delta;
25
+  int N, M, iKneeded, iKmin, iKmax, Max_Secs;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine;
28
+
29
+  if (argc != 8) { // provide some info
30
+
31
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
32
+    cout << endl << "Usage of Heis_DSF_par executable: " << endl;
33
+    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;
34
+    cout << endl << "Provide the following arguments:" << endl << endl;
35
+    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;
36
+    cout << "DP Delta \t\t Value of the anisotropy:  use positive real values only" << endl;
37
+    cout << "int N \t\t\t Length (number of sites) of the system:  use positive even integer values only" << endl;
38
+    cout << "int M \t\t\t Number of down spins:  use positive integer values between 1 and N/2" << endl;
39
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  0 and N" << endl;
40
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
41
+    cout << endl << "EXAMPLE: " << endl << endl;
42
+    cout << "mpiexec -np 8 Heis_DSF_par z 1.0 100 40 0 100 600" << endl << endl;
43
+
44
+    return(0);
45
+  }
46
+
47
+  else { // (argc == 8) correct nr of arguments
48
+    whichDSF = *argv[1];
49
+    Delta = atof(argv[2]);
50
+    N = atoi(argv[3]);
51
+    M = atoi(argv[4]);
52
+    iKmin = atoi(argv[5]);
53
+    iKmax = atoi(argv[6]);
54
+    Max_Secs = atoi(argv[7]);
55
+  }
56
+
57
+  DP supercycle_time = 600.0; // allotted time per supercycle
58
+
59
+  if (Max_Secs <= supercycle_time + 300) JSCerror("Please allow more time in Heis_DSF_par.");
60
+
61
+  MPI::Init(argc, argv);
62
+
63
+  DP tstart = MPI::Wtime();
64
+  
65
+  int rank = MPI::COMM_WORLD.Get_rank();
66
+  int nr_processors = MPI::COMM_WORLD.Get_size();
67
+
68
+  if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
69
+
70
+  refine = true;
71
+
72
+  // ASSUMPTION:  preexisting files (raw, thr, ...) exist for the run.
73
+  
74
+  // IMPORTANT PRECONDITION:  no flags are being raised in General_Scan in parallel mode, so
75
+  // the preinitializing serial run must be extensive enough to have flagged all base/type s necessary.
76
+
77
+  DP tnow = MPI::Wtime();
78
+
79
+  while (tnow - tstart < Max_Secs - supercycle_time - 300) { // space for one more supercycle, + 5 minutes safety
80
+
81
+    //cout << "rank " << rank << " ready to prepare." << endl;
82
+
83
+    if (rank == 0)
84
+      // Split up thread list into chunks, one per processor
85
+      Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors);
86
+    
87
+    //cout << "rank " << rank << " done preparing, ready to scan." << endl;
88
+
89
+    // Barrier synchronization, to make sure other processes wait for process of rank 0 
90
+    // to have finished splitting up the thr file into pieces before starting:
91
+    MPI_Barrier (MPI::COMM_WORLD);
92
+    
93
+    // then everybody gets going on their own chunk !
94
+    Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax,
95
+	       supercycle_time, target_sumrule, refine, rank, nr_processors);
96
+
97
+    //cout << "rank " << rank << " finished scanning, reached wrapup stage." << endl;
98
+    
99
+    // Another barrier synchronization 
100
+    MPI_Barrier (MPI::COMM_WORLD);
101
+
102
+    // Now that everybody is done, digest data into unique files    
103
+    if (rank == 0) 
104
+      Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, nr_processors);
105
+
106
+    //cout << "rank " << rank << " passed wrapup stage." << endl;
107
+
108
+    // Another barrier synchronization 
109
+    MPI_Barrier (MPI::COMM_WORLD);    
110
+
111
+    tnow = MPI::Wtime();
112
+
113
+  } // while (tnow - tstart...
114
+
115
+
116
+  MPI::Finalize();
117
+
118
+  return(0);
119
+}
120
+

+ 75
- 0
src/EXECS/Heis_DSF_par_Prepare.cc View File

@@ -0,0 +1,75 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's C++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Heis_DSF_par_Prepare.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+//#include "mpi.h" // not needed for Prepare
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP Delta;
25
+  int N, M, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  if (argc < 9) { // provide some info
30
+
31
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
32
+    cout << endl << "Usage of Heis_DSF_par_Prepare executable: " << endl;
33
+    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;
34
+    cout << endl << "Provide the following arguments:" << endl << endl;
35
+    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;
36
+    cout << "DP Delta \t\t Value of the anisotropy:  use positive real values only" << endl;
37
+    cout << "int N \t\t\t Length (number of sites) of the system:  use positive even integer values only" << endl;
38
+    cout << "int M \t\t\t Number of down spins:  use positive integer values between 1 and N/2" << endl;
39
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  0 and N" << endl;
40
+    cout << "int paralevel" << endl;
41
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
42
+    cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
43
+
44
+    return(0);
45
+  }
46
+
47
+  else { // correct nr of arguments
48
+    int n = 1;
49
+    whichDSF = *argv[n++];
50
+    Delta = atof(argv[n++]);
51
+    N = atoi(argv[n++]);
52
+    M = atoi(argv[n++]);
53
+    iKmin = atoi(argv[n++]);
54
+    iKmax = atoi(argv[n++]);
55
+    paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
56
+    if (argc != 9 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in Heis_DSF_par_Prepare.");
57
+
58
+    Vect<int> rank_lower_paralevels(paralevel - 1);
59
+    Vect<int> nr_processors_lower_paralevels(paralevel - 1);
60
+    for (int i = 0; i < paralevel - 1; ++i) {
61
+      rank_lower_paralevels[i] = atoi(argv[n++]);
62
+      nr_processors_lower_paralevels[i] = atoi(argv[n++]);
63
+    }
64
+    nr_processors_at_newlevel = atoi(argv[n++]);
65
+
66
+    string defaultScanStatename = "";
67
+    
68
+    // Split up thread list into chunks, one per processor
69
+    Prepare_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
70
+    
71
+  }
72
+
73
+  return(0);
74
+}
75
+

+ 127
- 0
src/EXECS/Heis_DSF_par_Run.cc View File

@@ -0,0 +1,127 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Heis_DSF_par_Run.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+#include "mpi.h"
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP Delta;
25
+  int N, M, iKmin, iKmax, Max_Secs, supercycle_time, paralevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  if (argc < 10) { // provide some info
30
+
31
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
32
+    cout << endl << "Usage of Heis_DSF_par_Run executable: " << endl;
33
+    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;
34
+    cout << endl << "Provide the following arguments:" << endl << endl;
35
+    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;
36
+    cout << "DP Delta \t\t Value of the anisotropy:  use positive real values only" << endl;
37
+    cout << "int N \t\t\t Length (number of sites) of the system:  use positive even integer values only" << endl;
38
+    cout << "int M \t\t\t Number of down spins:  use positive integer values between 1 and N/2" << endl;
39
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  0 and N" << endl;
40
+    cout << "int paralevel" << endl;
41
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
42
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
43
+    cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
44
+    cout << endl << "EXAMPLE: " << endl << endl;
45
+    cout << "mpiexec -np 8 Heis_DSF_par_Run z 1 128 64 0 128 [**UPDATE]" << endl << endl;
46
+
47
+    return(0);
48
+  }
49
+
50
+  //else { // (argc == 9) correct nr of arguments
51
+  int n = 1;
52
+  whichDSF = *argv[n++];
53
+  Delta = atof(argv[n++]);
54
+  N = atoi(argv[n++]);
55
+  M = atoi(argv[n++]);
56
+  iKmin = atoi(argv[n++]);
57
+  iKmax = atoi(argv[n++]);
58
+  paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
59
+  if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in Heis_DSF_par_Run.");
60
+  Vect<int> rank_lower_paralevels(paralevel - 1);
61
+  Vect<int> nr_processors_lower_paralevels(paralevel - 1);
62
+  for (int i = 0; i < paralevel - 1; ++i) {
63
+    rank_lower_paralevels[i] = atoi(argv[n++]);
64
+    nr_processors_lower_paralevels[i] = atoi(argv[n++]);
65
+  }
66
+  Max_Secs = atoi(argv[n++]);
67
+  supercycle_time = atoi(argv[n++]);
68
+  //}
69
+
70
+  //DP supercycle_time = 600.0; // allotted time per supercycle
71
+
72
+  if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in Heis_DSF_par_Run.");
73
+
74
+  MPI::Init(argc, argv);
75
+  
76
+  DP tstart = MPI::Wtime();
77
+  
78
+  int rank_here = MPI::COMM_WORLD.Get_rank();
79
+  int nr_processors_here = MPI::COMM_WORLD.Get_size();
80
+
81
+  Vect<int> rank (paralevel);
82
+  Vect<int> nr_processors (paralevel);
83
+  for (int i = 0; i < paralevel - 1; ++i) {
84
+    rank[i] = rank_lower_paralevels[i];
85
+    nr_processors[i] = nr_processors_lower_paralevels[i];
86
+  }
87
+  rank[paralevel-1] = rank_here;
88
+  nr_processors[paralevel-1] = nr_processors_here;
89
+
90
+  if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
91
+
92
+  refine = true;
93
+
94
+  // ASSUMPTION:  preexisting files (raw, thr, ...) exist for the run.
95
+  
96
+
97
+  DP tnow = MPI::Wtime();
98
+
99
+  string defaultScanStatename = "";
100
+
101
+  while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
102
+
103
+    // Barrier synchronization, to make sure other processes wait for process of rank 0 
104
+    // to have finished splitting up the thr file into pieces before starting:
105
+    MPI_Barrier (MPI::COMM_WORLD);
106
+    
107
+    // then everybody gets going on their own chunk !
108
+    Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, 
109
+	       supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
110
+    
111
+    // Another barrier synchronization 
112
+    MPI_Barrier (MPI::COMM_WORLD);
113
+    
114
+    // Now that everybody is done, digest data into unique files
115
+    
116
+    // Another barrier synchronization 
117
+    MPI_Barrier (MPI::COMM_WORLD);    
118
+
119
+    tnow = MPI::Wtime();
120
+
121
+  } // while (tnow - tstart...
122
+
123
+  MPI::Finalize();
124
+
125
+  return(0);
126
+}
127
+

+ 75
- 0
src/EXECS/Heis_DSF_par_Wrapup.cc View File

@@ -0,0 +1,75 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's C++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Heis_DSF_par_Prepare.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+//#include "mpi.h" // not needed for Prepare or Wrapup
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP Delta;
25
+  int N, M, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  if (argc < 9) { // provide some info
30
+
31
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
32
+    cout << endl << "Usage of Heis_DSF_par_Wrapup executable: " << endl;
33
+    cout << endl << "This function wraps up an ABACUS++G parallel mode run." << endl;
34
+    cout << endl << "Provide the following arguments:" << endl << endl;
35
+    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;
36
+    cout << "DP Delta \t\t Value of the anisotropy:  use positive real values only" << endl;
37
+    cout << "int N \t\t\t Length (number of sites) of the system:  use positive even integer values only" << endl;
38
+    cout << "int M \t\t\t Number of down spins:  use positive integer values between 1 and N/2" << endl;
39
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  0 and N" << endl;
40
+    cout << "int paralevel" << endl;
41
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
42
+    cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
43
+
44
+    return(0);
45
+  }
46
+
47
+  else { // correct nr of arguments
48
+    int n = 1;
49
+    whichDSF = *argv[n++];
50
+    Delta = atof(argv[n++]);
51
+    N = atoi(argv[n++]);
52
+    M = atoi(argv[n++]);
53
+    iKmin = atoi(argv[n++]);
54
+    iKmax = atoi(argv[n++]);
55
+    paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
56
+    if (argc != 9 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in Heis_DSF_par_Wrapup.");
57
+
58
+    Vect<int> rank_lower_paralevels(paralevel - 1);
59
+    Vect<int> nr_processors_lower_paralevels(paralevel - 1);
60
+    for (int i = 0; i < paralevel - 1; ++i) {
61
+      rank_lower_paralevels[i] = atoi(argv[n++]);
62
+      nr_processors_lower_paralevels[i] = atoi(argv[n++]);
63
+    }
64
+    nr_processors_at_newlevel = atoi(argv[n++]);
65
+
66
+    string defaultScanStatename = "";
67
+    
68
+    // Split up thread list into chunks, one per processor
69
+    Wrapup_Parallel_Scan_Heis (whichDSF, Delta, N, M, iKmin, iKmax, paralevel, rank_lower_paralevels, nr_processors_lower_paralevels, nr_processors_at_newlevel);
70
+    
71
+  }
72
+
73
+  return(0);
74
+}
75
+

+ 116
- 0
src/EXECS/LiebLin_Catalogue_Fixed_c_k_Nscaling.cc View File

@@ -0,0 +1,116 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_Catalogue_Fixed_c_k_Nscaling.cc
10
+
11
+Purpose:  Produces sets of data files for correlations, increasing system size at fixed c and momentum.
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 7) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of LiebLin_Catalogue_Fixed_c_k_Nscaling executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
31
+    //cout << "int Nc \t\t number of steps in interaction value" << endl;
32
+    //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;
33
+    //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;
34
+    cout << "int kfact \t\t momentum factor: momemntum will be set to kfact * kF/4" << endl;
35
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
36
+    cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
37
+    cout << "int Max_Secs \t\t Allowed computational time" << endl;
38
+  }
39
+
40
+  else { // correct nr of arguments
41
+    int ia = 1;
42
+    char whichDSF = *argv[ia++];
43
+    DP c_int = atof(argv[ia++]);
44
+    int kfact = atoi(argv[ia++]);
45
+    DP kBT = atof(argv[ia++]);
46
+    DP target_sumrule = atof(argv[ia++]);
47
+    int Max_Secs = atoi(argv[ia++]);
48
+    
49
+
50
+    //clock_t StartTime = clock();
51
+    double StartTime = omp_get_wtime();
52
+
53
+    //clock_t ActualTime = StartTime;
54
+    double ActualTime = omp_get_wtime();
55
+
56
+    int Secs_left = Max_Secs;
57
+
58
+    int iN = 0;
59
+
60
+    int nN = 12;
61
+    Vect<int> Nv(nN);
62
+    Nv[0] = 160; Nv[1] = 192; Nv[2] = 224; Nv[3] = 256;
63
+    Nv[4] = 320; Nv[5] = 384; Nv[6] = 448; Nv[7] = 512;
64
+    Nv[8] = 640; Nv[9] = 768; Nv[10] = 896; Nv[11] = 1024;
65
+
66
+    for (int iN = 0; iN < nN; ++iN) {
67
+
68
+      int N = Nv[iN];
69
+      DP L = N;
70
+      int iKmin = (kfact * N)/8;
71
+      int iKmax = iKmin;
72
+      DP srsat = 0.0;
73
+      bool refine = false;
74
+
75
+      stringstream SRC_stringstream;  string SRC_string;
76
+      Data_File_Name (SRC_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
77
+      SRC_stringstream << ".src";
78
+      SRC_string = SRC_stringstream.str();    const char* SRC_Cstr = SRC_string.c_str();
79
+      
80
+      fstream srcfile;
81
+      srcfile.open(SRC_Cstr, fstream::in);    
82
+      if (srcfile.fail()) {
83
+	srsat = 0.0;
84
+	refine = false;
85
+      }
86
+      else {
87
+	srcfile >> srsat;
88
+	refine = true;
89
+      }
90
+      srcfile.close();
91
+
92
+      ActualTime = omp_get_wtime();
93
+      Secs_left = int(Max_Secs - (ActualTime - StartTime));
94
+
95
+      if (srsat < target_sumrule && Secs_left > Max_Secs/2) 
96
+	// Improve the icmin calculation by one chunk:
97
+	Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Secs_left, target_sumrule, refine);
98
+
99
+      ActualTime = omp_get_wtime();
100
+
101
+      //Secs_left = int(60*Max_minutes - double(ActualTime - StartTime)/CLOCKS_PER_SEC);
102
+      Secs_left = int(Max_Secs - (ActualTime - StartTime));
103
+      cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl;
104
+
105
+      if (Secs_left < 60) {
106
+	cout << "Breaking out after N = " << N << " since time left = " << Secs_left << endl;
107
+	break;
108
+      }
109
+
110
+    } // while there is time      
111
+
112
+  } // else if arguments given OK
113
+
114
+  return(0);
115
+}
116
+

+ 62
- 0
src/EXECS/LiebLin_DSF.cc View File

@@ -0,0 +1,62 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF.cc
10
+
11
+Purpose:  main function for ABACUS++ for LiebLin gas
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 11) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
31
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
32
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
33
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
34
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
35
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
36
+    cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
37
+    cout << "bool refine \t\t Is this a refinement of earlier calculations ?  (0 == false, 1 == true)" << endl;
38
+    cout << endl << "EXAMPLE: " << endl << endl;
39
+    cout << "LiebLin_DSF d 1.0 100.0 100 0 200 0.56 600 1.0 0" << endl << endl;
40
+  }
41
+
42
+  else { // (argc == 10), correct nr of arguments
43
+    char whichDSF = *argv[1];
44
+    DP c_int = atof(argv[2]);
45
+    DP L = atof(argv[3]);
46
+    int N = atoi(argv[4]);
47
+    int iKmin = atoi(argv[5]);
48
+    int iKmax = atoi(argv[6]);
49
+    DP kBT = atof(argv[7]);
50
+    int Max_Secs = atoi(argv[8]);
51
+    DP target_sumrule = atof(argv[9]);
52
+    bool refine = (atoi(argv[10]) == 1);
53
+
54
+    //cout << "target_sumrule = " << target_sumrule << endl;
55
+
56
+    //Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine, 0, 1);
57
+    Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine);
58
+  }
59
+
60
+  return(0);
61
+}
62
+

+ 97
- 0
src/EXECS/LiebLin_DSF_GeneralState.cc View File

@@ -0,0 +1,97 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_GeneralState.cc
10
+
11
+Purpose:  function for ABACUS++ for LiebLin gas, on general states
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 11) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
31
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
32
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
33
+    cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
34
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
35
+    //cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
36
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
37
+    cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
38
+    cout << "bool refine \t\t Is this a refinement of earlier calculations ?  (0 == false, 1 == true)" << endl;
39
+    cout << endl << "EXAMPLE: " << endl << endl;
40
+    cout << "LiebLin_DSF d 1.0 100.0 100 0 200 0.56 600 1.0 0" << endl << endl;
41
+  }
42
+
43
+  else { // (argc == 10), correct nr of arguments
44
+    int n = 1;
45
+    char whichDSF = *argv[n++];
46
+    DP c_int = atof(argv[n++]);
47
+    DP L = atof(argv[n++]);
48
+    int N = atoi(argv[n++]);
49
+    char* Ix2filenameprefix = argv[n++];
50
+    int iKmin = atoi(argv[n++]);
51
+    int iKmax = atoi(argv[n++]);
52
+    //DP kBT = atof(argv[n++]);
53
+    int Max_Secs = atoi(argv[n++]);
54
+    DP target_sumrule = atof(argv[n++]);
55
+    bool refine = (atoi(argv[n++]) == 1);
56
+
57
+    // Read the Ix2 from the file:
58
+    Vect<int> Ix2_input(N);
59
+    ifstream Ix2_input_file;
60
+    stringstream filenamestrstream;
61
+    filenamestrstream << Ix2filenameprefix;
62
+    string defaultScanStatename = filenamestrstream.str();
63
+    filenamestrstream << ".Ix2";
64
+    string filenamestr = filenamestrstream.str();
65
+    const char* filename_Cstr = filenamestr.c_str();
66
+    Ix2_input_file.open(filename_Cstr);
67
+    if (Ix2_input_file.fail()) {
68
+      cout << filename_Cstr << endl;
69
+      JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
70
+    }
71
+    for (int i = 0; i < N; ++i) {
72
+      Ix2_input_file >> Ix2_input[i];
73
+      //cout << i << "\t" << Ix2_input[i] << endl;
74
+    }
75
+
76
+    // Now define the AveragingState
77
+    LiebLin_Bethe_State AveragingState(c_int, L, N);
78
+    AveragingState.Ix2 = Ix2_input;
79
+    AveragingState.Compute_All(true);
80
+
81
+    //cout << "Averaging state: " << AveragingState << endl;
82
+
83
+    //Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine, 0, 1);
84
+    //Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine);
85
+
86
+    //void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax, 
87
+    //		  int Max_Secs, DP target_sumrule, bool refine, int paralevel, Vect<int> rank, Vect<int> nr_processors)
88
+    // Simplified function call of the above:
89
+    //void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax, 
90
+    //		  int Max_Secs, DP target_sumrule, bool refine)
91
+    Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine);
92
+
93
+  }
94
+
95
+  return(0);
96
+}
97
+

+ 106
- 0
src/EXECS/LiebLin_DSF_GeneralState_par_Prepare.cc View File

@@ -0,0 +1,106 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_GeneralState_par_Prepare.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+//#include "mpi.h" // not needed for Prepare
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L, kBT;
25
+  int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+  char* Ix2filenameprefix;
29
+
30
+  if (argc < 10) { // provide some info
31
+
32
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
33
+    cout << endl << "Usage of LiebLin_DSF_par_Prepare executable: " << endl;
34
+    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;
35
+    cout << endl << "Provide the following arguments:" << endl << endl;
36
+    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;
37
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
38
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
39
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
40
+    cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
41
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
42
+    //cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
43
+    cout << "int paralevel" << endl;
44
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
45
+    cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
46
+
47
+    return(0);
48
+  }
49
+
50
+  else { // correct nr of arguments
51
+    int n = 1;
52
+    whichDSF = *argv[n++];
53
+    c_int = atof(argv[n++]);
54
+    L = atof(argv[n++]);
55
+    N = atoi(argv[n++]);
56
+    Ix2filenameprefix = argv[n++];
57
+    iKmin = atoi(argv[n++]);
58
+    iKmax = atoi(argv[n++]);
59
+    //kBT = atof(argv[n++]);
60
+    paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
61
+    if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_GeneralState_par_Prepare.");
62
+
63
+    Vect<int> rank_lower_paralevels(paralevel - 1);
64
+    Vect<int> nr_processors_lower_paralevels(paralevel - 1);
65
+
66
+    for (int i = 0; i < paralevel - 1; ++i) {
67
+      rank_lower_paralevels[i] = atoi(argv[n++]);
68
+      nr_processors_lower_paralevels[i] = atoi(argv[n++]);
69
+    }
70
+    nr_processors_at_newlevel = atoi(argv[n++]);
71
+
72
+
73
+    // Read the Ix2 from the file:
74
+    Vect<int> Ix2_input(N);
75
+    ifstream Ix2_input_file;
76
+    stringstream filenamestrstream;
77
+    filenamestrstream << Ix2filenameprefix;
78
+    string defaultScanStatename = filenamestrstream.str();
79
+    /*
80
+    filenamestrstream << ".Ix2";
81
+    string filenamestr = filenamestrstream.str();
82
+    const char* filename_Cstr = filenamestr.c_str();
83
+    Ix2_input_file.open(filename_Cstr);
84
+    if (Ix2_input_file.fail()) {
85
+      cout << filename_Cstr << endl;
86
+      JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
87
+    }
88
+    for (int i = 0; i < N; ++i) {
89
+      Ix2_input_file >> Ix2_input[i];
90
+      //cout << i << "\t" << Ix2_input[i] << endl;
91
+    }
92
+
93
+    // Define the AveragingState
94
+    LiebLin_Bethe_State AveragingState(c_int, L, N);
95
+    AveragingState.Ix2 = Ix2_input;
96
+    //AveragingState.Compute_All(true);
97
+    */
98
+
99
+    // Split up thread list into chunks, one per processor
100
+    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);
101
+    
102
+  }
103
+
104
+  return(0);
105
+}
106
+

+ 153
- 0
src/EXECS/LiebLin_DSF_GeneralState_par_Run.cc View File

@@ -0,0 +1,153 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_GeneralState_par_Run.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+#include "mpi.h"
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L, kBT;
25
+  int N, iKmin, iKmax, Max_Secs, paralevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+  char* Ix2filenameprefix;
29
+
30
+  if (argc < 10) { // provide some info
31
+
32
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
33
+    cout << endl << "Usage of LiebLin_DSF_par executable: " << endl;
34
+    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;
35
+    cout << endl << "Provide the following arguments:" << endl << endl;
36
+    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;
37
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
38
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
39
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
40
+    cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
41
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
42
+    //cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
43
+    cout << "int paralevel" << endl;
44
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
45
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
46
+    //cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
47
+
48
+    return(0);
49
+  }
50
+
51
+  //else { // correct nr of arguments
52
+  int n = 1;
53
+  whichDSF = *argv[n++];
54
+  c_int = atof(argv[n++]);
55
+  L = atof(argv[n++]);
56
+  N = atoi(argv[n++]);
57
+  Ix2filenameprefix = argv[n++];
58
+  iKmin = atoi(argv[n++]);
59
+  iKmax = atoi(argv[n++]);
60
+  //kBT = atof(argv[n++]);
61
+  paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
62
+  if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
63
+  Vect<int> rank_lower_paralevels(paralevel - 1);
64
+  Vect<int> nr_processors_lower_paralevels(paralevel - 1);
65
+  for (int i = 0; i < paralevel - 1; ++i) {
66
+    rank_lower_paralevels[i] = atoi(argv[n++]);
67
+    nr_processors_lower_paralevels[i] = atoi(argv[n++]);
68
+  }
69
+  Max_Secs = atoi(argv[n++]);
70
+  //  supercycle_time = atoi(argv[n++]);
71
+  //}
72
+
73
+  //DP supercycle_time = 600.0; // allotted time per supercycle
74
+
75
+  if (Max_Secs <= 120) JSCerror("Please allow more time in LiebLin_DSF_par_Run.");
76
+
77
+  int Max_Secs_used = Max_Secs - 120;
78
+
79
+  MPI::Init(argc, argv);
80
+  
81
+  DP tstart = MPI::Wtime();
82
+  
83
+  int rank_here = MPI::COMM_WORLD.Get_rank();
84
+  int nr_processors_here = MPI::COMM_WORLD.Get_size();
85
+
86
+  // Read the Ix2 from the file:
87
+  Vect<int> Ix2_input(N);
88
+  ifstream Ix2_input_file;
89
+  stringstream filenamestrstream;
90
+  filenamestrstream << Ix2filenameprefix;
91
+  string defaultScanStatename = filenamestrstream.str();
92
+  filenamestrstream << ".Ix2";
93
+  string filenamestr = filenamestrstream.str();
94
+  const char* filename_Cstr = filenamestr.c_str();
95
+  Ix2_input_file.open(filename_Cstr);
96
+  if (Ix2_input_file.fail()) {
97
+    cout << filename_Cstr << endl;
98
+    JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
99
+  }
100
+  for (int i = 0; i < N; ++i) {
101
+    Ix2_input_file >> Ix2_input[i];
102
+    //cout << i << "\t" << Ix2_input[i] << endl;
103
+  }
104
+  
105
+  // Now define the AveragingState
106
+  LiebLin_Bethe_State AveragingState(c_int, L, N);
107
+  AveragingState.Ix2 = Ix2_input;
108
+  AveragingState.Compute_All(true);
109
+  
110
+
111
+  Vect<int> rank (paralevel);
112
+  Vect<int> nr_processors (paralevel);
113
+  for (int i = 0; i < paralevel - 1; ++i) {
114
+    rank[i] = rank_lower_paralevels[i];
115
+    nr_processors[i] = nr_processors_lower_paralevels[i];
116
+  }
117
+  rank[paralevel-1] = rank_here;
118
+  nr_processors[paralevel-1] = nr_processors_here;
119
+
120
+  if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
121
+
122
+  refine = true;
123
+
124
+  // ASSUMPTION:  preexisting files (raw, thr, ...) exist for the run.
125
+  
126
+
127
+  DP tnow = MPI::Wtime();
128
+
129
+  
130
+  //while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
131
+  if (Max_Secs_used > 0) { 
132
+
133
+    // Barrier synchronization
134
+    MPI_Barrier (MPI::COMM_WORLD);
135
+    
136
+    // then everybody gets going on their own chunk !
137
+    //Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 
138
+    //Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
139
+    //	       supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
140
+    Scan_LiebLin (whichDSF, AveragingState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine, paralevel, rank, nr_processors);
141
+    
142
+    // Another barrier synchronization 
143
+    MPI_Barrier (MPI::COMM_WORLD);
144
+    
145
+    tnow = MPI::Wtime();
146
+
147
+  } // while (tnow - tstart...
148
+
149
+  MPI::Finalize();
150
+
151
+  return(0);
152
+}
153
+

+ 104
- 0
src/EXECS/LiebLin_DSF_GeneralState_par_Wrapup.cc View File

@@ -0,0 +1,104 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_par_Prepare.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+//#include "mpi.h" // not needed for Prepare
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L, kBT;
25
+  int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+  char* Ix2filenameprefix;
29
+
30
+  if (argc < 10) { // provide some info
31
+
32
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
33
+    cout << endl << "Usage of LiebLin_DSF_par_Wrapup executable: " << endl;
34
+    cout << endl << "This function wraps up an ABACUS++ parallel mode run." << endl;
35
+    cout << endl << "Provide the following arguments:" << endl << endl;
36
+    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;
37
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
38
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
39
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
40
+    cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
41
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
42
+    //cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
43
+    cout << "int paralevel" << endl;
44
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
45
+    cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
46
+
47
+    return(0);
48
+  }
49
+
50
+  else { // correct nr of arguments
51
+    int n = 1;
52
+    whichDSF = *argv[n++];
53
+    c_int = atof(argv[n++]);
54
+    L = atof(argv[n++]);
55
+    N = atoi(argv[n++]);
56
+    Ix2filenameprefix = argv[n++];
57
+    iKmin = atoi(argv[n++]);
58
+    iKmax = atoi(argv[n++]);
59
+    //kBT = atof(argv[n++]);
60
+    paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
61
+    if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
62
+
63
+    Vect<int> rank_lower_paralevels(paralevel - 1);
64
+    Vect<int> nr_processors_lower_paralevels(paralevel - 1);
65
+    for (int i = 0; i < paralevel - 1; ++i) {
66
+      rank_lower_paralevels[i] = atoi(argv[n++]);
67
+      nr_processors_lower_paralevels[i] = atoi(argv[n++]);
68
+    }
69
+    nr_processors_at_newlevel = atoi(argv[n++]);
70
+
71
+    // Read the Ix2 from the file:
72
+    Vect<int> Ix2_input(N);
73
+    ifstream Ix2_input_file;
74
+    stringstream filenamestrstream;
75
+    filenamestrstream << Ix2filenameprefix;
76
+    string defaultScanStatename = filenamestrstream.str();
77
+    /*
78
+    filenamestrstream << ".Ix2";
79
+    string filenamestr = filenamestrstream.str();
80
+    const char* filename_Cstr = filenamestr.c_str();
81
+    Ix2_input_file.open(filename_Cstr);
82
+    if (Ix2_input_file.fail()) {
83
+      cout << filename_Cstr << endl;
84
+      JSCerror("Could not open Ix2 input file in LiebLin_DSF_GeneralState");
85
+    }
86
+    for (int i = 0; i < N; ++i) {
87
+      Ix2_input_file >> Ix2_input[i];
88
+      //cout << i << "\t" << Ix2_input[i] << endl;
89
+    }
90
+
91
+    // Define the AveragingState
92
+    LiebLin_Bethe_State AveragingState(c_int, L, N);
93
+    AveragingState.Ix2 = Ix2_input;
94
+    //AveragingState.Compute_All(true);
95
+    */
96
+    
97
+    // Digest files into a unique one for the latest paralevel:
98
+    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);
99
+    
100
+  }
101
+
102
+  return(0);
103
+}
104
+

+ 84
- 0
src/EXECS/LiebLin_DSF_MosesState.cc View File

@@ -0,0 +1,84 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF.cc
10
+
11
+Purpose:  main function for ABACUS++ for LiebLin gas
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 13) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of LiebLin_DSF_MosesState executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
31
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
32
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
33
+    cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
34
+    cout << "int DIl \t\t shift of left  sea as compared to its ground state position" << endl; 
35
+    cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl; 
36
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
37
+    //cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
38
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
39
+    cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
40
+    cout << "bool refine \t\t Is this a refinement of earlier calculations ?  (0 == false, 1 == true)" << endl;
41
+    cout << endl << "EXAMPLE: " << endl << endl;
42
+    cout << "LiebLin_DSF_MosesState d 1.0 100.0 100 50 -30 20 0 200 600 1.0 0" << endl << endl;
43
+  }
44
+
45
+  else { // (argc == 13), correct nr of arguments
46
+    char whichDSF = *argv[1];
47
+    DP c_int = atof(argv[2]);
48
+    DP L = atof(argv[3]);
49
+    int N = atoi(argv[4]);
50
+    int Nl = atoi(argv[5]);
51
+    //int Nr = N - Nl;
52
+    int DIl = atoi(argv[6]);
53
+    int DIr = atoi(argv[7]);
54
+    int iKmin = atoi(argv[8]);
55
+    int iKmax = atoi(argv[9]);
56
+    //DP kBT = atof(argv[7]);
57
+    int Max_Secs = atoi(argv[10]);
58
+    DP target_sumrule = atof(argv[11]);
59
+    bool refine = (atoi(argv[12]) == 1);
60
+
61
+    // Define the Moses state:
62
+    LiebLin_Bethe_State MosesState (c_int, L, N);
63
+
64
+    // Split the sea:
65
+    for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
66
+    for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
67
+
68
+    MosesState.Compute_All (true);
69
+
70
+    //cout << MosesState << endl;
71
+
72
+    // Handy default name:
73
+    stringstream defaultScanStatename_strstream;
74
+    defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
75
+    string defaultScanStatename = defaultScanStatename_strstream.str();
76
+
77
+    // Compute the correlation:
78
+    Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, Max_Secs, target_sumrule, refine);
79
+
80
+  }
81
+
82
+  return(0);
83
+}
84
+

+ 139
- 0
src/EXECS/LiebLin_DSF_MosesState_par.cc View File

@@ -0,0 +1,139 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_par.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+#include "mpi.h"
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L;
25
+  int N, Nl, DIl, DIr, iKmin, iKmax, Max_Secs, supercycle_time;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  DP kBT = 0.0; // dummy
30
+
31
+  if (argc != 12) { // provide some info
32
+
33
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
34
+    cout << endl << "Usage of LiebLin_DSF_MosesState_par executable: " << endl;
35
+    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;
36
+    cout << endl << "Provide the following arguments:" << endl << endl;
37
+    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;
38
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
39
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
40
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
41
+    cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
42
+    cout << "int DIl \t\t shift of left  sea as compared to its ground state position" << endl; 
43
+    cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl; 
44
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
45
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
46
+    cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
47
+    cout << endl << "EXAMPLE: " << endl << endl;
48
+    cout << "mpiexec -np 8 LiebLin_DSF_MosesState_par d 1.0 100.0 100 50 -30 20 -400 400 3600 600" << endl << endl;
49
+
50
+    return(0);
51
+  }
52
+
53
+  else { // (argc == 11) correct nr of arguments
54
+    whichDSF = *argv[1];
55
+    c_int = atof(argv[2]);
56
+    L = atof(argv[3]);
57
+    N = atoi(argv[4]);
58
+    Nl = atoi(argv[5]);
59
+    DIl = atoi(argv[6]);
60
+    DIr = atoi(argv[7]);
61
+    iKmin = atoi(argv[8]);
62
+    iKmax = atoi(argv[9]);
63
+    Max_Secs = atoi(argv[10]);
64
+    supercycle_time = atoi(argv[11]);
65
+  }
66
+
67
+  //DP supercycle_time = 600.0; // allotted time per supercycle
68
+
69
+  if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par.");
70
+
71
+  MPI::Init(argc, argv);
72
+  
73
+  DP tstart = MPI::Wtime();
74
+  
75
+  int rank = MPI::COMM_WORLD.Get_rank();
76
+  int nr_processors = MPI::COMM_WORLD.Get_size();
77
+
78
+  if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
79
+
80
+  refine = true;
81
+
82
+  // ASSUMPTION:  preexisting files (raw, thr, ...) exist for the run.
83
+  
84
+
85
+  DP tnow = MPI::Wtime();
86
+
87
+  // Define the Moses state:
88
+  LiebLin_Bethe_State MosesState (c_int, L, N);
89
+
90
+  // Split the sea:
91
+  for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
92
+  for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
93
+
94
+  MosesState.Compute_All (true);
95
+
96
+  // Handy default name:
97
+  stringstream defaultScanStatename_strstream;
98
+  defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
99
+  string defaultScanStatename = defaultScanStatename_strstream.str();
100
+
101
+  MPI_Barrier (MPI::COMM_WORLD);
102
+
103
+  while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
104
+
105
+    if (rank == 0)
106
+      // Split up thread list into chunks, one per processor
107
+      //Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
108
+      Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
109
+    
110
+    // Barrier synchronization, to make sure other processes wait for process of rank 0 
111
+    // to have finished splitting up the thr file into pieces before starting:
112
+    MPI_Barrier (MPI::COMM_WORLD);
113
+    
114
+    // then everybody gets going on their own chunk !
115
+    //Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 
116
+    //Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, supercycle_time, target_sumrule, refine, rank, nr_processors);
117
+    Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time, target_sumrule, refine, rank, nr_processors);
118
+    
119
+    // Another barrier synchronization 
120
+    MPI_Barrier (MPI::COMM_WORLD);
121
+    
122
+    // Now that everybody is done, digest data into unique files
123
+    
124
+    if (rank == 0) 
125
+      //Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
126
+      Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
127
+
128
+    // Another barrier synchronization 
129
+    MPI_Barrier (MPI::COMM_WORLD);    
130
+
131
+    tnow = MPI::Wtime();
132
+
133
+  } // while (tnow - tstart...
134
+
135
+  MPI::Finalize();
136
+
137
+  return(0);
138
+}
139
+

+ 96
- 0
src/EXECS/LiebLin_DSF_MosesState_par_Prepare.cc View File

@@ -0,0 +1,96 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_par_Prepare.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+//#include "mpi.h" // not needed for Prepare
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L;
25
+  int N, Nl, DIl, DIr, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  DP kBT = 0.0; // dummy
30
+
31
+  if (argc < 12) { // provide some info
32
+
33
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
34
+    cout << endl << "Usage of LiebLin_DSF_MosesState_par_Prepare executable: " << endl;
35
+    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;
36
+    cout << endl << "Provide the following arguments:" << endl << endl;
37
+    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;
38
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
39
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
40
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
41
+    cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
42
+    cout << "int DIl \t\t shift of left  sea as compared to its ground state position" << endl; 
43
+    cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl; 
44
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
45
+    cout << "int paralevel" << endl;
46
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
47
+    cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
48
+
49
+    return(0);
50
+  }
51
+
52
+  else { // correct nr of arguments
53
+    int n = 1;
54
+    whichDSF = *argv[n++];
55
+    c_int = atof(argv[n++]);
56
+    L = atof(argv[n++]);
57
+    N = atoi(argv[n++]);
58
+    Nl = atoi(argv[n++]);
59
+    DIl = atoi(argv[n++]);
60
+    DIr = atoi(argv[n++]);
61
+    iKmin = atoi(argv[n++]);
62
+    iKmax = atoi(argv[n++]);
63
+    paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
64
+    if (argc != 12 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_MosesState_par_Prepare.");
65
+
66
+    Vect<int> rank_lower_paralevels(paralevel - 1);
67
+    Vect<int> nr_processors_lower_paralevels(paralevel - 1);
68
+    for (int i = 0; i < paralevel - 1; ++i) {
69
+      rank_lower_paralevels[i] = atoi(argv[n++]);
70
+      nr_processors_lower_paralevels[i] = atoi(argv[n++]);
71
+    }
72
+    nr_processors_at_newlevel = atoi(argv[n++]);
73
+
74
+    // Define the Moses state:
75
+    LiebLin_Bethe_State MosesState (c_int, L, N);
76
+    
77
+    // Split the sea:
78
+    for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
79
+    for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
80
+    
81
+    MosesState.Compute_All (true);
82
+    
83
+    // Handy default name:
84
+    stringstream defaultScanStatename_strstream;
85
+    defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
86
+    string defaultScanStatename = defaultScanStatename_strstream.str();
87
+    
88
+    
89
+    // Split up thread list into chunks, one per processor
90
+    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);
91
+    
92
+  }
93
+
94
+  return(0);
95
+}
96
+

+ 162
- 0
src/EXECS/LiebLin_DSF_MosesState_par_Run.cc View File

@@ -0,0 +1,162 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_par.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+#include "mpi.h"
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L;
25
+  int N, Nl, DIl, DIr, iKmin, iKmax, Max_Secs, supercycle_time, paralevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  DP kBT = 0.0; // dummy
30
+
31
+  if (argc < 13) { // provide some info
32
+
33
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
34
+    cout << endl << "Usage of LiebLin_DSF_MosesState_par_Run executable: " << endl;
35
+    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;
36
+    cout << endl << "Provide the following arguments:" << endl << endl;
37
+    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;
38
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
39
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
40
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
41
+    cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
42
+    cout << "int DIl \t\t shift of left  sea as compared to its ground state position" << endl; 
43
+    cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl; 
44
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
45
+    cout << "int paralevel" << endl;
46
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
47
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
48
+    cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
49
+
50
+    return(0);
51
+  }
52
+
53
+  //else { // correct nr of arguments
54
+  int n = 1;
55
+  whichDSF = *argv[n++];
56
+  c_int = atof(argv[n++]);
57
+  L = atof(argv[n++]);
58
+  N = atoi(argv[n++]);
59
+  Nl = atoi(argv[n++]);
60
+  DIl = atoi(argv[n++]);
61
+  DIr = atoi(argv[n++]);
62
+  iKmin = atoi(argv[n++]);
63
+  iKmax = atoi(argv[n++]);
64
+  paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
65
+  if (argc != 13 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
66
+  Vect<int> rank_lower_paralevels(paralevel - 1);
67
+  Vect<int> nr_processors_lower_paralevels(paralevel - 1);
68
+  for (int i = 0; i < paralevel - 1; ++i) {
69
+    rank_lower_paralevels[i] = atoi(argv[n++]);
70
+    nr_processors_lower_paralevels[i] = atoi(argv[n++]);
71
+  }
72
+  Max_Secs = atoi(argv[n++]);
73
+  supercycle_time = atoi(argv[n++]);
74
+  //}
75
+
76
+  //DP supercycle_time = 600.0; // allotted time per supercycle
77
+
78
+  if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par_Run.");
79
+
80
+  MPI::Init(argc, argv);
81
+  
82
+  DP tstart = MPI::Wtime();
83
+  
84
+  int rank_here = MPI::COMM_WORLD.Get_rank();
85
+  int nr_processors_here = MPI::COMM_WORLD.Get_size();
86
+
87
+  //cout << "rank " << rank_here << " out of " << nr_processors_here << " ready to go." << endl;
88
+
89
+  Vect<int> rank (paralevel);
90
+  Vect<int> nr_processors (paralevel);
91
+  for (int i = 0; i < paralevel - 1; ++i) {
92
+    rank[i] = rank_lower_paralevels[i];
93
+    nr_processors[i] = nr_processors_lower_paralevels[i];
94
+  }
95
+  rank[paralevel-1] = rank_here;
96
+  nr_processors[paralevel-1] = nr_processors_here;
97
+
98
+  if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
99
+
100
+  refine = true;
101
+
102
+  // ASSUMPTION:  preexisting files (raw, thr, ...) exist for the run.
103
+  
104
+
105
+  DP tnow = MPI::Wtime();
106
+
107
+  // Define the Moses state:
108
+  LiebLin_Bethe_State MosesState (c_int, L, N);
109
+  
110
+  // Split the sea:
111
+  for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
112
+  for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
113
+  
114
+  MosesState.Compute_All (true);
115
+  
116
+  // Handy default name:
117
+  stringstream defaultScanStatename_strstream;
118
+  defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
119
+  string defaultScanStatename = defaultScanStatename_strstream.str();
120
+  
121
+  //cout << "rank " << rank_here << " out of " << nr_processors_here << " waiting at barrier." << endl;
122
+
123
+  MPI_Barrier (MPI::COMM_WORLD);
124
+  
125
+
126
+  while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
127
+
128
+    //if (rank == 0)
129
+      // Split up thread list into chunks, one per processor
130
+      //Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
131
+      //Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
132
+    
133
+    // Barrier synchronization, to make sure other processes wait for process of rank 0 
134
+    // to have finished splitting up the thr file into pieces before starting:
135
+    MPI_Barrier (MPI::COMM_WORLD);
136
+    
137
+    // then everybody gets going on their own chunk !
138
+    //Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 
139
+    //Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
140
+    Scan_LiebLin (whichDSF, MosesState, defaultScanStatename, iKmin, iKmax, supercycle_time, target_sumrule, refine, paralevel, rank, nr_processors);
141
+    
142
+    // Another barrier synchronization 
143
+    MPI_Barrier (MPI::COMM_WORLD);
144
+    
145
+    // Now that everybody is done, digest data into unique files
146
+    
147
+    //if (rank == 0) 
148
+      //Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
149
+      //Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
150
+
151
+    // Another barrier synchronization 
152
+    MPI_Barrier (MPI::COMM_WORLD);    
153
+
154
+    tnow = MPI::Wtime();
155
+
156
+  } // while (tnow - tstart...
157
+
158
+  MPI::Finalize();
159
+
160
+  return(0);
161
+}
162
+

+ 96
- 0
src/EXECS/LiebLin_DSF_MosesState_par_Wrapup.cc View File

@@ -0,0 +1,96 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_MosesState_par_Wrapup.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+//#include "mpi.h" // not needed for Prepare
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L;
25
+  int N, Nl, DIl, DIr, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  DP kBT = 0.0; // dummy
30
+
31
+  if (argc < 12) { // provide some info
32
+
33
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
34
+    cout << endl << "Usage of LiebLin_DSF_MosesState_par_Wrapup executable: " << endl;
35
+    cout << endl << "This function wraps up an ABACUS++ parallel mode run." << endl;
36
+    cout << endl << "Provide the following arguments:" << endl << endl;
37
+    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;
38
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
39
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
40
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
41
+    cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
42
+    cout << "int DIl \t\t shift of left  sea as compared to its ground state position" << endl; 
43
+    cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl; 
44
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
45
+    cout << "int paralevel" << endl;
46
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
47
+    cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
48
+
49
+    return(0);
50
+  }
51
+
52
+  else { // correct nr of arguments
53
+    int n = 1;
54
+    whichDSF = *argv[n++];
55
+    c_int = atof(argv[n++]);
56
+    L = atof(argv[n++]);
57
+    N = atoi(argv[n++]);
58
+    Nl = atoi(argv[n++]);
59
+    DIl = atoi(argv[n++]);
60
+    DIr = atoi(argv[n++]);
61
+    iKmin = atoi(argv[n++]);
62
+    iKmax = atoi(argv[n++]);
63
+    paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
64
+    if (argc != 12 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_MosesState_par_Prepare.");
65
+
66
+    Vect<int> rank_lower_paralevels(paralevel - 1);
67
+    Vect<int> nr_processors_lower_paralevels(paralevel - 1);
68
+    for (int i = 0; i < paralevel - 1; ++i) {
69
+      rank_lower_paralevels[i] = atoi(argv[n++]);
70
+      nr_processors_lower_paralevels[i] = atoi(argv[n++]);
71
+    }
72
+    nr_processors_at_newlevel = atoi(argv[n++]);
73
+
74
+    // Define the Moses state:
75
+    LiebLin_Bethe_State MosesState (c_int, L, N);
76
+    
77
+    // Split the sea:
78
+    for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] += 2 * DIl;
79
+    for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
80
+    
81
+    MosesState.Compute_All (true);
82
+    
83
+    // Handy default name:
84
+    stringstream defaultScanStatename_strstream;
85
+    defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
86
+    string defaultScanStatename = defaultScanStatename_strstream.str();
87
+    
88
+    
89
+    // Digest files into a unique one for the latest paralevel:
90
+    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);
91
+    
92
+  }
93
+
94
+  return(0);
95
+}
96
+

+ 99
- 0
src/EXECS/LiebLin_DSF_over_Ensemble.cc View File

@@ -0,0 +1,99 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_over_Ensemble.cc
10
+
11
+Purpose:  main function for ABACUS++T for LiebLin gas, averaging over an Ensemble.
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 10) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
31
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
32
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
33
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
34
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
35
+    //cout << "int nstates \t\t\t Number of states to be considered in the ensemble" << endl;
36
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
37
+    //cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
38
+    cout << "bool refine \t\t Is this a refinement of earlier calculations ?  (0 == false, 1 == true)" << endl;
39
+    cout << endl << "EXAMPLE: " << endl << endl;
40
+    cout << "LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 0.56 10 600 0" << endl << endl;
41
+  }
42
+
43
+  else { // (argc == 10), correct nr of arguments
44
+    char whichDSF = *argv[1];
45
+    DP c_int = atof(argv[2]);
46
+    DP L = atof(argv[3]);
47
+    int N = atoi(argv[4]);
48
+    int iKmin = atoi(argv[5]);
49
+    int iKmax = atoi(argv[6]);
50
+    DP kBT = atof(argv[7]);
51
+    //int nstates_req = atoi(argv[8]);
52
+    int Max_Secs = atoi(argv[8]);
53
+    bool refine = (atoi(argv[9]) == 1);
54
+
55
+    // Start by constructing (or loading) the state ensemble.
56
+
57
+    LiebLin_Diagonal_State_Ensemble ensemble;
58
+
59
+    stringstream ensfilestrstream;
60
+    //ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
61
+    ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
62
+    string ensfilestr = ensfilestrstream.str();
63
+    const char* ensfile_Cstr = ensfilestr.c_str();
64
+
65
+    if (!refine) { // Construct the state ensemble
66
+      //ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT, nstates_req);
67
+      ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT);
68
+      ensemble.Save(ensfile_Cstr); // Save the ensemble
69
+    }
70
+
71
+    else { // load the ensemble data
72
+      ensemble.Load(c_int, L, N, ensfile_Cstr);
73
+    }
74
+
75
+    // Now perform the DSF calculation over each state in the ensemble, distributing the time according to the weight
76
+
77
+    for (int ns = 0; ns < ensemble.nstates; ++ns) {
78
+      //void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax, 
79
+      //int Max_Secs, DP target_sumrule, bool refine, int rank, int nr_processors)
80
+      //Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, int(Max_Secs * ensemble.weight[ns]), 1.0e+6, refine, 0, 1);
81
+      Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, int(Max_Secs * ensemble.weight[ns]), 1.0e+6, refine);
82
+    }
83
+
84
+    // Evaluate the f-sumrule
85
+    stringstream FSR_stringstream;  string FSR_string;
86
+    Data_File_Name (FSR_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
87
+    FSR_stringstream << "_ns_" << ensemble.nstates << ".fsr";
88
+    FSR_string = FSR_stringstream.str();    const char* FSR_Cstr = FSR_string.c_str();
89
+    
90
+    DP Chem_Pot = 0.0;
91
+
92
+    Evaluate_F_Sumrule (whichDSF, c_int, L, N, kBT, ensemble.nstates, Chem_Pot, iKmin, iKmax, FSR_Cstr);
93
+
94
+
95
+  } // correct nr of arguments
96
+
97
+  return(0);
98
+}
99
+

+ 191
- 0
src/EXECS/LiebLin_DSF_over_Ensemble_par.cc View File

@@ -0,0 +1,191 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_over_Ensemble_par.cc
10
+
11
+Purpose:  main function for ABACUS for LiebLin gas, averaging over an Ensemble, parallel implementation.
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+#include "mpi.h"
17
+
18
+using namespace std;
19
+using namespace JSC;
20
+
21
+
22
+int main(int argc, char* argv[]) 
23
+{
24
+
25
+  if (argc != 10) { // provide some info
26
+
27
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
28
+    cout << endl << "Usage of LiebLin_DSF_Tgt0 executable: " << endl;
29
+    cout << endl << "Provide the following arguments:" << endl << endl;
30
+    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;
31
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
32
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
33
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
34
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
35
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
36
+    //cout << "int nstates \t\t\t Number of states to be considered in the ensemble" << endl;
37
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
38
+    //cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
39
+    cout << "bool refine \t\t Is this a refinement of earlier calculations ?  (0 == false, 1 == true)" << endl;
40
+    cout << endl << "EXAMPLE: " << endl << endl;
41
+    cout << "LiebLin_DSF_over_Ensemble d 1.0 100.0 100 0 200 0.56 10 600 0" << endl << endl;
42
+  }
43
+
44
+  else { // (argc == 10), correct nr of arguments
45
+    char whichDSF = *argv[1];
46
+    DP c_int = atof(argv[2]);
47
+    DP L = atof(argv[3]);
48
+    int N = atoi(argv[4]);
49
+    int iKmin = atoi(argv[5]);
50
+    int iKmax = atoi(argv[6]);
51
+    DP kBT = atof(argv[7]);
52
+    //int nstates_req = atoi(argv[8]);
53
+    int Max_Secs = atoi(argv[8]);
54
+    bool refine = (atoi(argv[9]) == 1);
55
+
56
+    if (refine == false) JSCerror("Please run the serial version of LiebLin_DSF_over_Ensemble first.");
57
+
58
+    MPI::Init(argc, argv);
59
+    
60
+    DP tstart = MPI::Wtime();
61
+    
62
+    int rank = MPI::COMM_WORLD.Get_rank();
63
+    int nr_processors = MPI::COMM_WORLD.Get_size();
64
+    
65
+    if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
66
+
67
+
68
+    // Start by constructing (or loading) the state ensemble.
69
+
70
+    LiebLin_Diagonal_State_Ensemble ensemble;
71
+
72
+    stringstream ensfilestrstream;
73
+    //ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
74
+    ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
75
+    string ensfilestr = ensfilestrstream.str();
76
+    const char* ensfile_Cstr = ensfilestr.c_str();
77
+
78
+    if (!refine) { // Construct the state ensemble
79
+      //ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT, nstates_req);
80
+      ensemble = LiebLin_Thermal_Saddle_Point_Ensemble (c_int, L, N, kBT);
81
+      ensemble.Save(ensfile_Cstr); // Save the ensemble
82
+    }
83
+
84
+    else { // load the ensemble data
85
+      ensemble.Load(c_int, L, N, ensfile_Cstr);
86
+    }
87
+
88
+    MPI_Barrier (MPI::COMM_WORLD);
89
+
90
+    // Now perform the DSF calculation over each state in the ensemble
91
+
92
+    /* Original implementation: Scan always called serially. Superseded by version below, using successive parallel scans on each state in the ensemble.
93
+    int nDSFperproc = ensemble.nstates/nr_processors + 1;
94
+    //if (ensemble.nstates % nr_processors) JSCerror("Use nr_processors * integer multiple == ensemble.nstates in LiebLin_DSF_over_Ensemble_par.");
95
+    
96
+    // Processor with rank r does all 
97
+
98
+    int ns;
99
+    int Max_Secs_used = Max_Secs/nDSFperproc;
100
+
101
+    for (int ir = 0; ir < nDSFperproc; ++ir) {
102
+      ns = rank + ir * nr_processors;
103
+      //void Scan_LiebLin (char whichDSF, LiebLin_Bethe_State AveragingState, string defaultScanStatename, int iKmin, int iKmax, 
104
+      //int Max_Secs, DP target_sumrule, bool refine, int rank, int nr_processors)
105
+      if (ns < ensemble.nstates) {
106
+	//cout << "Processor rank " << rank << " going for ns = " << ns << " out of " << ensemble.nstates << endl;
107
+	Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, Max_Secs_used, 1.0e+6, refine, 0, 1);
108
+      }
109
+    }
110
+    */
111
+
112
+    // Version 2013 04 24:
113
+    // Makes use of a parallel scan for each state in the ensemble, in succession.
114
+    // Code is simple adaptation of LiebLin_DSF_par executable code.
115
+
116
+    int Max_Secs_used = Max_Secs/ensemble.nstates;
117
+
118
+    DP supercycle_time = 600.0; // allotted time per supercycle
119
+
120
+    if (Max_Secs_used <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par.");
121
+
122
+    // Main loop over ensemble:
123
+    for (int ns = 0; ns < ensemble.nstates; ++ns) { 
124
+      
125
+      tstart = MPI::Wtime();
126
+      DP tnow = MPI::Wtime();      
127
+
128
+      string defaultScanStatename = ensemble.state[ns].label;
129
+
130
+      while (tnow - tstart < Max_Secs_used - supercycle_time) { // space for one more supercycle
131
+
132
+	if (rank == 0)
133
+	  // Split up thread list into chunks, one per processor
134
+	  //Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
135
+	  Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
136
+    
137
+	// Barrier synchronization, to make sure other processes wait for process of rank 0 
138
+	// to have finished splitting up the thr file into pieces before starting:
139
+	MPI_Barrier (MPI::COMM_WORLD);
140
+	
141
+	// then everybody gets going on their own chunk !
142
+	//Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 
143
+	//Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
144
+	//supercycle_time, target_sumrule, refine, rank, nr_processors);
145
+	Scan_LiebLin (whichDSF, ensemble.state[ns], ensemble.state[ns].label, iKmin, iKmax, supercycle_time, 1.0e+6, refine, rank, nr_processors);
146
+    
147
+	// Another barrier synchronization 
148
+	MPI_Barrier (MPI::COMM_WORLD);
149
+	
150
+	// Now that everybody is done, digest data into unique files
151
+    
152
+	if (rank == 0) 
153
+	  //Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
154
+	  Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
155
+
156
+	// Another barrier synchronization 
157
+	MPI_Barrier (MPI::COMM_WORLD);    
158
+
159
+	tnow = MPI::Wtime();
160
+	
161
+      } // while (tnow - tstart...
162
+
163
+    } // for ns
164
+
165
+
166
+    MPI_Barrier (MPI::COMM_WORLD);
167
+
168
+
169
+    // Final wrapup of the data
170
+    if (rank == 0) {
171
+
172
+      // Evaluate the f-sumrule
173
+      stringstream FSR_stringstream;  string FSR_string;
174
+      Data_File_Name (FSR_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
175
+      FSR_stringstream << "_ns_" << ensemble.nstates << ".fsr";
176
+      FSR_string = FSR_stringstream.str();    const char* FSR_Cstr = FSR_string.c_str();
177
+      
178
+      DP Chem_Pot = 0.0;
179
+      
180
+      Evaluate_F_Sumrule (whichDSF, c_int, L, N, kBT, ensemble.nstates, Chem_Pot, iKmin, iKmax, FSR_Cstr);
181
+    }
182
+
183
+    MPI_Barrier (MPI::COMM_WORLD);
184
+
185
+  } // correct nr of arguments
186
+
187
+  MPI::Finalize();
188
+
189
+  return(0);
190
+}
191
+

+ 119
- 0
src/EXECS/LiebLin_DSF_par.cc View File

@@ -0,0 +1,119 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_par.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+#include "mpi.h"
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L, kBT;
25
+  int N, iKmin, iKmax, Max_Secs, supercycle_time;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  if (argc != 10) { // provide some info
30
+
31
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
32
+    cout << endl << "Usage of LiebLin_DSF_par executable: " << endl;
33
+    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;
34
+    cout << endl << "Provide the following arguments:" << endl << endl;
35
+    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;
36
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
37
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
38
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
39
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
40
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
41
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
42
+    cout << "int supercycle_time \t\t time for one supercycle (in seconds)" << endl;
43
+    cout << endl << "EXAMPLE: " << endl << endl;
44
+    cout << "mpiexec -np 8 LiebLin_DSF_MosesState_par d 1.0 100.0 100 -400 400 0.0 3600 600" << endl << endl;
45
+
46
+    return(0);
47
+  }
48
+
49
+  else { // (argc == 9) correct nr of arguments
50
+    whichDSF = *argv[1];
51
+    c_int = atof(argv[2]);
52
+    L = atof(argv[3]);
53
+    N = atoi(argv[4]);
54
+    iKmin = atoi(argv[5]);
55
+    iKmax = atoi(argv[6]);
56
+    kBT = atof(argv[7]);
57
+    Max_Secs = atoi(argv[8]);
58
+    supercycle_time = atoi(argv[9]);
59
+  }
60
+
61
+  //DP supercycle_time = 600.0; // allotted time per supercycle
62
+
63
+  if (Max_Secs <= supercycle_time) JSCerror("Please allow more time in LiebLin_DSF_par.");
64
+
65
+  MPI::Init(argc, argv);
66
+  
67
+  DP tstart = MPI::Wtime();
68
+  
69
+  int rank = MPI::COMM_WORLD.Get_rank();
70
+  int nr_processors = MPI::COMM_WORLD.Get_size();
71
+
72
+  if (nr_processors < 2) JSCerror("Give at least 2 processors to ABACUS++ parallel !");
73
+
74
+  refine = true;
75
+
76
+  // ASSUMPTION:  preexisting files (raw, thr, ...) exist for the run.
77
+  
78
+
79
+  DP tnow = MPI::Wtime();
80
+
81
+  string defaultScanStatename = "";
82
+
83
+  while (tnow - tstart < Max_Secs - supercycle_time - 120) { // space for one more supercycle, + 2 minutes safety
84
+
85
+    if (rank == 0)
86
+      // Split up thread list into chunks, one per processor
87
+      //Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
88
+      Prepare_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
89
+    
90
+    // Barrier synchronization, to make sure other processes wait for process of rank 0 
91
+    // to have finished splitting up the thr file into pieces before starting:
92
+    MPI_Barrier (MPI::COMM_WORLD);
93
+    
94
+    // then everybody gets going on their own chunk !
95
+    //Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 
96
+    Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
97
+	       supercycle_time, target_sumrule, refine, rank, nr_processors);
98
+    
99
+    // Another barrier synchronization 
100
+    MPI_Barrier (MPI::COMM_WORLD);
101
+    
102
+    // Now that everybody is done, digest data into unique files
103
+    
104
+    if (rank == 0) 
105
+      //Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, nr_processors);
106
+      Wrapup_Parallel_Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, defaultScanStatename, nr_processors);
107
+
108
+    // Another barrier synchronization 
109
+    MPI_Barrier (MPI::COMM_WORLD);    
110
+
111
+    tnow = MPI::Wtime();
112
+
113
+  } // while (tnow - tstart...
114
+
115
+  MPI::Finalize();
116
+
117
+  return(0);
118
+}
119
+

+ 77
- 0
src/EXECS/LiebLin_DSF_par_Prepare.cc View File

@@ -0,0 +1,77 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_par_Prepare.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+//#include "mpi.h" // not needed for Prepare
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L, kBT;
25
+  int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  if (argc < 10) { // provide some info
30
+
31
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
32
+    cout << endl << "Usage of LiebLin_DSF_par_Prepare executable: " << endl;
33
+    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;
34
+    cout << endl << "Provide the following arguments:" << endl << endl;
35
+    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;
36
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
37
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
38
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
39
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
40
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
41
+    cout << "int paralevel" << endl;
42
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
43
+    cout << "int nr_processors_at_new_level \t for this new parallelization level." << endl;
44
+
45
+    return(0);
46
+  }
47
+
48
+  else { // correct nr of arguments
49
+    int n = 1;
50
+    whichDSF = *argv[n++];
51
+    c_int = atof(argv[n++]);
52
+    L = atof(argv[n++]);
53
+    N = atoi(argv[n++]);
54
+    iKmin = atoi(argv[n++]);
55
+    iKmax = atoi(argv[n++]);
56
+    kBT = atof(argv[n++]);
57
+    paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
58
+    if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Prepare.");
59
+
60
+    Vect<int> rank_lower_paralevels(paralevel - 1);
61
+    Vect<int> nr_processors_lower_paralevels(paralevel - 1);
62
+    for (int i = 0; i < paralevel - 1; ++i) {
63
+      rank_lower_paralevels[i] = atoi(argv[n++]);
64
+      nr_processors_lower_paralevels[i] = atoi(argv[n++]);
65
+    }
66
+    nr_processors_at_newlevel = atoi(argv[n++]);
67
+
68
+    string defaultScanStatename = "";
69
+    
70
+    // Split up thread list into chunks, one per processor
71
+    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);
72
+    
73
+  }
74
+
75
+  return(0);
76
+}
77
+

+ 120
- 0
src/EXECS/LiebLin_DSF_par_Run.cc View File

@@ -0,0 +1,120 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_par_Run.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+#include "mpi.h"
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L, kBT;
25
+  int N, iKmin, iKmax, Max_Secs, paralevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  if (argc < 10) { // provide some info
30
+
31
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
32
+    cout << endl << "Usage of LiebLin_DSF_par_Run executable: " << endl;
33
+    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;
34
+    cout << endl << "Provide the following arguments:" << endl << endl;
35
+    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;
36
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
37
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
38
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
39
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
40
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
41
+    cout << "int paralevel" << endl;
42
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
43
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
44
+    cout << endl << "EXAMPLE: " << endl << endl;
45
+    cout << "mpiexec -np 8 LiebLin_DSF_par_Run d 1.0 100.0 100 0 400 0.0 1 3600" << endl << endl;
46
+
47
+    return(0);
48
+  }
49
+
50
+  int n = 1;
51
+  whichDSF = *argv[n++];
52
+  c_int = atof(argv[n++]);
53
+  L = atof(argv[n++]);
54
+  N = atoi(argv[n++]);
55
+  iKmin = atoi(argv[n++]);
56
+  iKmax = atoi(argv[n++]);
57
+  kBT = atof(argv[n++]);
58
+  paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
59
+  if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Run.");
60
+  Vect<int> rank_lower_paralevels(paralevel - 1);
61
+  Vect<int> nr_processors_lower_paralevels(paralevel - 1);
62
+  for (int i = 0; i < paralevel - 1; ++i) {
63
+    rank_lower_paralevels[i] = atoi(argv[n++]);
64
+    nr_processors_lower_paralevels[i] = atoi(argv[n++]);
65
+  }
66
+  Max_Secs = atoi(argv[n++]);
67
+
68
+  if (Max_Secs < 120) JSCerror("Please allow more time in LiebLin_DSF_par_Run.");
69
+
70
+  int Max_Secs_used = Max_Secs - 120;
71
+
72
+  MPI::Init(argc, argv);
73
+  
74
+  DP tstart = MPI::Wtime();
75
+  
76
+  int rank_here = MPI::COMM_WORLD.Get_rank();
77
+  int nr_processors_here = MPI::COMM_WORLD.Get_size();
78
+
79
+  Vect<int> rank (paralevel);
80
+  Vect<int> nr_processors (paralevel);
81
+  for (int i = 0; i < paralevel - 1; ++i) {
82
+    rank[i] = rank_lower_paralevels[i];
83
+    nr_processors[i] = nr_processors_lower_paralevels[i];
84
+  }
85
+  rank[paralevel-1] = rank_here;
86
+  nr_processors[paralevel-1] = nr_processors_here;
87
+
88
+  if (nr_processors_here < 2) JSCerror("Give at least 2 processors to ABACUS parallel !");
89
+
90
+  refine = true;
91
+
92
+  // ASSUMPTION:  preexisting files (raw, thr, ...) exist for the run.
93
+  
94
+
95
+  DP tnow = MPI::Wtime();
96
+
97
+  string defaultScanStatename = "";
98
+
99
+  if (Max_Secs_used > 0) { // space for 2 minutes safety
100
+
101
+    // Barrier synchronization
102
+    MPI_Barrier (MPI::COMM_WORLD);
103
+    
104
+    // then everybody gets going on their own chunk !
105
+    //Scan_LiebLin (whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 
106
+    Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT,
107
+		  Max_Secs_used, target_sumrule, refine, paralevel, rank, nr_processors);
108
+    
109
+    // Another barrier synchronization 
110
+    MPI_Barrier (MPI::COMM_WORLD);
111
+    
112
+    tnow = MPI::Wtime();
113
+
114
+  } 
115
+
116
+  MPI::Finalize();
117
+
118
+  return(0);
119
+}
120
+

+ 77
- 0
src/EXECS/LiebLin_DSF_par_Wrapup.cc View File

@@ -0,0 +1,77 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_par_Wrapup.cc
10
+
11
+Purpose:  Parallel version of ABACUS++ using MPICH.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+//#include "mpi.h" // not needed for Prepare or Wrapup
18
+
19
+using namespace JSC;
20
+
21
+int main(int argc, char *argv[])
22
+{
23
+  char whichDSF;
24
+  DP c_int, L, kBT;
25
+  int N, iKmin, iKmax, paralevel, nr_processors_at_newlevel;
26
+  DP target_sumrule = 1.0e+6;  // effectively deactivated here
27
+  bool refine = true;  // always true for parallel mode
28
+
29
+  if (argc < 10) { // provide some info
30
+
31
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
32
+    cout << endl << "Usage of LiebLin_DSF_par_Wrapup executable: " << endl;
33
+    cout << endl << "This function wraps up an ABACUS++ parallel mode run." << endl;
34
+    cout << endl << "Provide the following arguments:" << endl << endl;
35
+    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;
36
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
37
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
38
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
39
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
40
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
41
+    cout << "int paralevel" << endl;
42
+    cout << "rank[i], nr_processors[i] \t rank and nr_processors of each earlier paralevels." << endl;
43
+    cout << "int nr_processors_at_new_level \t for this latest parallelization level." << endl;
44
+
45
+    return(0);
46
+  }
47
+
48
+  else { // correct nr of arguments
49
+    int n = 1;
50
+    whichDSF = *argv[n++];
51
+    c_int = atof(argv[n++]);
52
+    L = atof(argv[n++]);
53
+    N = atoi(argv[n++]);
54
+    iKmin = atoi(argv[n++]);
55
+    iKmax = atoi(argv[n++]);
56
+    kBT = atof(argv[n++]);
57
+    paralevel = atoi(argv[n++]); // paralevel == 1 means that we have one layer of parallelization, so no previous rank and nr_processors to specify
58
+    if (argc != 10 + 2*(paralevel - 1)) JSCerror("Wrong nr of arguments in LiebLin_DSF_par_Wrapup.");
59
+
60
+    Vect<int> rank_lower_paralevels(paralevel - 1);
61
+    Vect<int> nr_processors_lower_paralevels(paralevel - 1);
62
+    for (int i = 0; i < paralevel - 1; ++i) {
63
+      rank_lower_paralevels[i] = atoi(argv[n++]);
64
+      nr_processors_lower_paralevels[i] = atoi(argv[n++]);
65
+    }
66
+    nr_processors_at_newlevel = atoi(argv[n++]);
67
+
68
+    string defaultScanStatename = "";
69
+    
70
+    // Digest files into a unique one for the latest paralevel:
71
+    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);
72
+    
73
+  }
74
+
75
+  return(0);
76
+}
77
+

+ 92
- 0
src/EXECS/LiebLin_DSF_tester.cc View File

@@ -0,0 +1,92 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_tester.cc
10
+
11
+Purpose:  allows for Ix2 manipulations (user-prompted) for LiebLin gas
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 6) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
31
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
32
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
33
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
34
+    cout << endl << "EXAMPLE: " << endl << endl;
35
+    cout << "LiebLin_DSF_tester d 1.0 100.0 100 0.56 " << endl << endl;
36
+  }
37
+
38
+  else { // (argc == 6), correct nr of arguments
39
+    char whichDSF = *argv[1];
40
+    DP c_int = atof(argv[2]);
41
+    DP L = atof(argv[3]);
42
+    int N = atoi(argv[4]);
43
+    DP kBT = atof(argv[5]);
44
+
45
+    //if (whichDSF != 'd') JSCerror("Other options not implemented yet in finite T Scan_LiebLin");
46
+
47
+    // Delta is the number of sites involved in the smoothing of the entropy
48
+    //int Delta = int(sqrt(N))/2;//6;//N/20;  
49
+
50
+    // Construct the finite-size saddle-point state:
51
+    //LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT, Delta);
52
+    LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
53
+    spstate.Compute_All(true);
54
+
55
+    LiebLin_Bethe_State estate = spstate;
56
+    if (whichDSF == 'o') estate = Remove_Particle_at_Center (spstate);
57
+    else if (whichDSF == 'g') estate = Add_Particle_at_Center (spstate);
58
+    if (whichDSF != 'd') estate.Compute_All(true);
59
+    cout << estate << endl;
60
+    Vect<int> OriginIx2 = estate.Ix2;
61
+
62
+    int Ix2old, Ix2new;
63
+    int again = 0;
64
+    string label_req;
65
+    do {
66
+      //cout << "Substitute Ix2:  which for which ?" << endl;
67
+      //cin >> Ix2old >> Ix2new;
68
+      //for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new;
69
+      //estate.Ix2.QuickSort();
70
+      cout << "Which label should the exc state be set to?" << endl;
71
+      cin >> label_req;
72
+      estate.Set_to_Label(label_req, OriginIx2);
73
+      estate.Compute_All(false);
74
+      cout << spstate << endl;
75
+      cout << estate;
76
+      if (whichDSF == 'd') 
77
+	cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Density_ME(spstate, estate))) << endl;
78
+      else if (whichDSF == 'o') 
79
+	cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(estate, spstate))) << endl;
80
+      else if (whichDSF == 'g') 
81
+	cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(spstate, estate))) << endl;
82
+
83
+      //cout << "Another try ? (1 == yes, 0 == no)" << endl;
84
+      again = 1;
85
+      cin >> again;
86
+    } while (again != 0);
87
+
88
+  }
89
+
90
+  return(0);
91
+}
92
+

+ 92
- 0
src/EXECS/LiebLin_DSF_tester_Ix2.cc View File

@@ -0,0 +1,92 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_tester.cc
10
+
11
+Purpose:  allows for Ix2 manipulations (user-prompted) for LiebLin gas
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 6) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
31
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
32
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
33
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
34
+    cout << endl << "EXAMPLE: " << endl << endl;
35
+    cout << "LiebLin_DSF_tester d 1.0 100.0 100 0.56 " << endl << endl;
36
+  }
37
+
38
+  else { // (argc == 6), correct nr of arguments
39
+    char whichDSF = *argv[1];
40
+    DP c_int = atof(argv[2]);
41
+    DP L = atof(argv[3]);
42
+    int N = atoi(argv[4]);
43
+    DP kBT = atof(argv[5]);
44
+
45
+    //if (whichDSF != 'd') JSCerror("Other options not implemented yet in finite T Scan_LiebLin");
46
+
47
+    // Delta is the number of sites involved in the smoothing of the entropy
48
+    //int Delta = int(sqrt(N))/2;//6;//N/20;  
49
+
50
+    // Construct the finite-size saddle-point state:
51
+    //LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT, Delta);
52
+    LiebLin_Bethe_State spstate = Canonical_Saddle_Point_State (c_int, L, N, kBT);
53
+    spstate.Compute_All(true);
54
+
55
+    LiebLin_Bethe_State estate = spstate;
56
+    if (whichDSF == 'o') estate = Remove_Particle_at_Center (spstate);
57
+    else if (whichDSF == 'g') estate = Add_Particle_at_Center (spstate);
58
+    if (whichDSF != 'd') estate.Compute_All(true);
59
+    cout << estate << endl;
60
+    Vect<int> OriginIx2 = estate.Ix2;
61
+
62
+    int Ix2old, Ix2new;
63
+    int again = 0;
64
+    string label_req;
65
+    do {
66
+      cout << "Substitute Ix2:  which for which ?" << endl;
67
+      cin >> Ix2old >> Ix2new;
68
+      for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new;
69
+      estate.Ix2.QuickSort();
70
+      //cout << "Which label should the exc state be set to?" << endl;
71
+      //cin >> label_req;
72
+      //estate.Set_to_Label(label_req, OriginIx2);
73
+      estate.Compute_All(false);
74
+      cout << spstate << endl;
75
+      cout << estate;
76
+      if (whichDSF == 'd') 
77
+	cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Density_ME(spstate, estate))) << endl;
78
+      else if (whichDSF == 'o') 
79
+	cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(estate, spstate))) << endl;
80
+      else if (whichDSF == 'g') 
81
+	cout << setprecision(16) << "estate.E - spstate.E = " << estate.E - spstate.E << "\tME = " << real(exp(ln_Psi_ME(spstate, estate))) << endl;
82
+
83
+      cout << "Another try ? (1 == yes, 0 == no)" << endl;
84
+      again = 1;
85
+      cin >> again;
86
+    } while (again != 0);
87
+
88
+  }
89
+
90
+  return(0);
91
+}
92
+

+ 120
- 0
src/EXECS/LiebLin_Data_Daemon.cc View File

@@ -0,0 +1,120 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_Data_Daemon.cc
10
+
11
+Purpose:  Produces sets of data files for correlations.
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 11) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of LiebLin_Data_Daemon executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP c_int_max \t\t Largest value of the interaction parameter:  use positive real values only" << endl;
31
+    cout << "int Nc \t\t number of steps in interaction value" << endl;
32
+    cout << "int cfact \t\t dividing factor (each new interaction value if 1/cfact times the previous)" << endl;
33
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
34
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
35
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
36
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
37
+    cout << "int Max_Hrs \t\t Allowed computational time:  (in hours)" << endl;
38
+  }
39
+
40
+  else { // (argc == 10), correct nr of arguments
41
+    int ia = 1;
42
+    char whichDSF = *argv[ia++];
43
+    DP c_int_max = atof(argv[ia++]);
44
+    int Nc = atoi(argv[ia++]);
45
+    int cfact = atoi(argv[ia++]);
46
+    DP L = atof(argv[ia++]);
47
+    int N = atoi(argv[ia++]);
48
+    int iKmin = atoi(argv[ia++]);
49
+    int iKmax = atoi(argv[ia++]);
50
+    DP kBT = atof(argv[ia++]);
51
+    int Max_Hrs = atoi(argv[ia++]);
52
+
53
+    // Individual computations are split into chuncks of Max_Hrs/(Nc * 4) 
54
+    //int Max_Secs = (Max_Hrs * 900)/Nc;
55
+    int Max_Secs = (Max_Hrs * 2700)/Nc; // to minimize wrapping up & restarting time
56
+
57
+    cout << "Data daemon will use chunks of " << Max_Secs << " seconds." << endl;
58
+
59
+    //clock_t StartTime = clock();
60
+    double StartTime = omp_get_wtime();
61
+
62
+    //clock_t ActualTime = StartTime;
63
+    double ActualTime = omp_get_wtime();
64
+
65
+    DP c_int;
66
+    DP target_sumrule = 1.0; 
67
+
68
+    //while (double(ActualTime - StartTime)/CLOCKS_PER_SEC < double(3600 * Max_Hrs - Max_Secs)) {
69
+    while (ActualTime - StartTime < double(3600 * Max_Hrs - Max_Secs)) {
70
+
71
+      Vect<DP> srsat(0.0, Nc);
72
+      Vect<bool> refine(false, Nc); 
73
+      DP srmin = 1.0;
74
+      int icmin = 0;
75
+
76
+      // Determine which correlation has the worst sum rule:
77
+      for (int ic = 0; ic < Nc; ++ic) {
78
+	c_int = c_int_max/pow(cfact, ic);
79
+	stringstream SRC_stringstream;  string SRC_string;
80
+	Data_File_Name (SRC_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
81
+	SRC_stringstream << ".src";
82
+	SRC_string = SRC_stringstream.str();    const char* SRC_Cstr = SRC_string.c_str();
83
+	
84
+	fstream srcfile;
85
+	srcfile.open(SRC_Cstr, fstream::in);    
86
+	if (srcfile.fail()) {
87
+	  srsat[ic] = 0.0;
88
+	  refine[ic] = false;
89
+	}
90
+	else {
91
+	  srcfile >> srsat[ic];
92
+	  refine[ic] = true;
93
+	}
94
+	if (srsat[ic] < srmin) {
95
+	  srmin = srsat[ic];
96
+	  icmin = ic;
97
+	}
98
+	srcfile.close();
99
+
100
+      } // for ic  
101
+
102
+      cout << "srsat min found: " << srmin << "\t for c = " << c_int_max/pow(cfact, icmin) << ". Now refining this." 
103
+	//<< " Time left: " << 3600* Max_Hrs - (ActualTime - StartTime)/CLOCKS_PER_SEC << " seconds." << endl;
104
+	   << " Time left: " << 3600* Max_Hrs - (ActualTime - StartTime) << " seconds." << endl;
105
+
106
+      // Improve the icmin calculation by one chunk:
107
+      Scan_LiebLin (whichDSF, c_int_max/pow(cfact, icmin), L, N, iKmin, iKmax, kBT, Max_Secs, target_sumrule, refine[icmin]);
108
+
109
+      //ActualTime = clock();
110
+      ActualTime = omp_get_wtime();
111
+
112
+    } // while there is time      
113
+
114
+    cout << "Wrapping up, time's up." << endl;
115
+
116
+  } // else if arguments given OK
117
+
118
+  return(0);
119
+}
120
+

+ 104
- 0
src/EXECS/LiebLin_Data_Daemon_Nscaling.cc View File

@@ -0,0 +1,104 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_Data_Daemon_Nscaling.cc
10
+
11
+Purpose:  Produces sets of data files for correlations, increasing system size at fixed c and momentum window.
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 9) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of LiebLin_Data_Daemon_Nscaling executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
31
+    //cout << "int Nc \t\t number of steps in interaction value" << endl;
32
+    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;
33
+    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;
34
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
35
+    cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
36
+    cout << "int Max_minutes \t\t Allowed computational time:  (in minutes)" << endl;
37
+  }
38
+
39
+  else { // (argc == 10), correct nr of arguments
40
+    int ia = 1;
41
+    char whichDSF = *argv[ia++];
42
+    DP c_int = atof(argv[ia++]);
43
+    int Nstep = atoi(argv[ia++]);
44
+    int iKmin_Nstep = atoi(argv[ia++]);
45
+    int iKmax_Nstep = atoi(argv[ia++]);
46
+    DP kBT = atof(argv[ia++]);
47
+    DP target_sumrule = atof(argv[ia++]);
48
+    int Max_minutes = atoi(argv[ia++]);
49
+    
50
+
51
+    //clock_t StartTime = clock();
52
+    double StartTime = omp_get_wtime();
53
+
54
+    //clock_t ActualTime = StartTime;
55
+    double ActualTime = omp_get_wtime();
56
+
57
+    int Secs_left = 60* Max_minutes;
58
+
59
+    int iN = 0;
60
+    
61
+    while (Secs_left > 0) {
62
+
63
+      iN += 1;
64
+      int N = Nstep * iN;
65
+      DP L = N;
66
+      int iKmin = iKmin_Nstep * iN;
67
+      int iKmax = iKmax_Nstep * iN;
68
+      DP srsat = 0.0;
69
+      bool refine = false;
70
+
71
+      stringstream SRC_stringstream;  string SRC_string;
72
+      Data_File_Name (SRC_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
73
+      SRC_stringstream << ".src";
74
+      SRC_string = SRC_stringstream.str();    const char* SRC_Cstr = SRC_string.c_str();
75
+      
76
+      fstream srcfile;
77
+      srcfile.open(SRC_Cstr, fstream::in);    
78
+      if (srcfile.fail()) {
79
+	srsat = 0.0;
80
+	refine = false;
81
+      }
82
+      else {
83
+	srcfile >> srsat;
84
+	refine = true;
85
+      }
86
+      srcfile.close();
87
+
88
+      // Improve the icmin calculation by one chunk:
89
+      Scan_LiebLin (whichDSF, c_int, L, N, iKmin, iKmax, kBT, Secs_left, target_sumrule, refine);
90
+
91
+      ActualTime = clock();
92
+
93
+      //Secs_left = int(60*Max_minutes - double(ActualTime - StartTime)/CLOCKS_PER_SEC);
94
+      Secs_left = int(60*Max_minutes - (ActualTime - StartTime));
95
+
96
+      cout << "Done with N = " << N << ". Time left = " << Secs_left << " seconds." << endl;
97
+
98
+    } // while there is time      
99
+
100
+  } // else if arguments given OK
101
+
102
+  return(0);
103
+}
104
+

+ 149
- 0
src/EXECS/LiebLin_Fourier_ssf_to_Qsqx.cc View File

@@ -0,0 +1,149 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_Fourier_to_Qsqx.cc
10
+
11
+Purpose:  Compute the Q(x)^2 expectation value for LiebLin, where Q(x) = \int_0^x dx \rho(x).
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 9) { // provide some info
24
+
25
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
26
+    cout << endl << "Usage of LiebLin_Fourier_to_Qsqx executable: " << endl;
27
+    cout << endl << "Provide the following arguments:" << endl << endl;
28
+    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;
29
+    cout << "DP c_int \t\t Value of the interaction parameter" << endl;
30
+    cout << "DP L \t\t\t Length of the system" << endl;
31
+    cout << "int N \t\t\t Number of particles" << endl;
32
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
33
+    cout << "DP kBT \t\t Temperature" << endl;
34
+    cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
35
+  }
36
+
37
+  else { // (argc == 9), correct nr of arguments
38
+    char whichDSF = *argv[1];
39
+    DP c_int = atof(argv[2]);
40
+    DP L = atof(argv[3]);
41
+    int N = atoi(argv[4]);
42
+    int iKmin = atoi(argv[5]);
43
+    int iKmax = atoi(argv[6]);
44
+    DP kBT = atof(argv[7]);
45
+    int Npts_x = atoi(argv[8]);
46
+    // Force Npts_x
47
+    //Npts_x = L;
48
+
49
+    if (whichDSF != 'd') JSCerror("Must use whichDSF == d in LiebLin_Fourier_ssf_to_Qsqx");
50
+
51
+    stringstream filenameprefix;
52
+    Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
53
+    string prefix = filenameprefix.str();    
54
+
55
+    stringstream RAW_stringstream;    string RAW_string;
56
+    RAW_stringstream << prefix << ".raw";
57
+    RAW_string = RAW_stringstream.str();    const char* RAW_Cstr = RAW_string.c_str();
58
+    ifstream RAW_infile;
59
+    RAW_infile.open(RAW_Cstr);
60
+    if (RAW_infile.fail()) {
61
+      cout << RAW_Cstr << endl;
62
+      JSCerror("Could not open RAW_infile... "); 
63
+    }
64
+
65
+    // We also read the f-sumrule file, to correct for missing intensity.
66
+    stringstream FSR_stringstream;    string FSR_string;
67
+    FSR_stringstream << prefix << ".fsr";
68
+    FSR_string = FSR_stringstream.str();    const char* FSR_Cstr = FSR_string.c_str();
69
+    ifstream FSR_infile;
70
+    FSR_infile.open(FSR_Cstr);
71
+    if (FSR_infile.fail()) {
72
+      cout << FSR_Cstr << endl;
73
+      JSCerror("Could not open FSR_infile... "); 
74
+    }
75
+
76
+    stringstream SFT_stringstream;    string SFT_string;
77
+    SFT_stringstream << prefix << ".Qsqx";
78
+    SFT_string = SFT_stringstream.str();    const char* SFT_Cstr = SFT_string.c_str();
79
+    ofstream SFT_outfile;
80
+    SFT_outfile.open(SFT_Cstr);
81
+    if (SFT_outfile.fail()) JSCerror("Could not open SFT_outfile... "); 
82
+
83
+    // First compute the static structure factor from the RAW data:
84
+
85
+    Vect_DP SSF(0.0, iKmax - iKmin + 1);
86
+
87
+    DP omega;
88
+    int iK;
89
+    DP FF;
90
+    //int conv;
91
+    DP dev;
92
+    string label;
93
+
94
+    while (RAW_infile.peek() != EOF) {
95
+      RAW_infile >> omega >> iK >> FF >> dev >> label;
96
+      if (iK >= iKmin && iK <= iKmax) {
97
+	SSF[iK - iKmin] += FF * FF;
98
+      }
99
+    }
100
+    RAW_infile.close();
101
+
102
+    // Reset proper normalization:
103
+    DP normalization = twoPI * L; 
104
+    for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) SSF[iK] *= normalization/twoPI; // twoPI from integral over omega
105
+
106
+
107
+    // Now define real-space coordinates: between 0 and L/2
108
+    Vect_DP xlattice(Npts_x);
109
+    for (int i = 0; i < Npts_x; ++i) xlattice[i] = (i + 0.5) * 0.5* L/Npts_x;
110
+
111
+    // Now the correlation at x:
112
+    Vect_DP FT(0.0, Npts_x);
113
+
114
+    DP pioverL = PI/L;
115
+
116
+    // Fourier transform:
117
+    for (int ix = 0; ix < Npts_x; ++ix) {
118
+      for (int iK = 1; iK <= iKmax; ++iK) {
119
+	FT[ix] += SSF[iK - iKmin] * pow(sin(pioverL * iK * xlattice[ix])/iK, 2.0);
120
+      }
121
+      // Reset proper normalization: 1/L from space FT,
122
+      FT[ix] *= 2.0*L/(PI * PI);
123
+
124
+      // Outside of window iKmin, iKmax, we take the DSF to be a constant with delta function 
125
+      // at free energy k^2, so DSF = 2\pi N/L \delta(\omega - k^2) (to fit f-sumrule)
126
+      // so SSF becomes N/L.
127
+      // We thus need to correct above by adding
128
+      // \frac{1}{L} \sum_{-\infty}^{iKmin - 1} SSF e^{ikx} + \frac{1}{L} \sum_{iKmax + 1}^\infty SSF e^{ikx}
129
+      // Resumming carefully:
130
+      //FTre[ix] += (sin(twopioverL * (iKmin - 0.5) * xlattice[ix]) - sin(twopioverL * (iKmax + 0.5) * xlattice[ix])) 
131
+      //* N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
132
+      //FTim[ix] += (-cos(twopioverL * (iKmin - 0.5) * xlattice[ix]) + cos(twopioverL * (iKmax + 0.5) * xlattice[ix])) 
133
+      //* N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
134
+    }
135
+
136
+
137
+    // Output to file:
138
+    for (int ix = 0; ix < Npts_x; ++ix) {
139
+      if (ix > 0) SFT_outfile << endl;
140
+      //SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix];
141
+      SFT_outfile << xlattice[ix]/L << "\t" << FT[ix];
142
+    }
143
+
144
+    SFT_outfile.close();
145
+  }
146
+
147
+  return(0);
148
+
149
+}

+ 132
- 0
src/EXECS/LiebLin_Fourier_to_t_equal_x.cc View File

@@ -0,0 +1,132 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_Fourier_to_t_equal_x.cc
10
+
11
+Purpose:  Fourier transform to static space correlator for LiebLin.
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 10) { // provide some info
24
+
25
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
26
+    cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
27
+    cout << endl << "Provide the following arguments:" << endl << endl;
28
+    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;
29
+    cout << "DP c_int \t\t Value of the interaction parameter" << endl;
30
+    cout << "DP L \t\t\t Length of the system" << endl;
31
+    cout << "int N \t\t\t Number of particles" << endl;
32
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
33
+    cout << "DP kBT \t\t Temperature" << endl;
34
+    cout << "int Npts_t \t Number of points in time for the Fourier transform" << endl;
35
+    cout << "DP t_max \t Max time to be used" << endl;
36
+  }
37
+
38
+  else { // (argc == 10), correct nr of arguments
39
+    char whichDSF = *argv[1];
40
+    DP c_int = atof(argv[2]);
41
+    DP L = atof(argv[3]);
42
+    int N = atoi(argv[4]);
43
+    int iKmin = atoi(argv[5]);
44
+    int iKmax = atoi(argv[6]);
45
+    DP kBT = atof(argv[7]);
46
+    int Npts_t = atoi(argv[8]);
47
+    DP t_max = atof(argv[9]);
48
+
49
+    // Momentum business: use symmetry
50
+    if (iKmin != 0) JSCerror("LiebLin_Fourier_to_t_equal_x only implemented for raw files with iKmin == 0.");
51
+
52
+    stringstream filenameprefix;
53
+    Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
54
+    string prefix = filenameprefix.str();    
55
+
56
+    stringstream RAW_stringstream;    string RAW_string;
57
+    RAW_stringstream << prefix << ".raw";
58
+    RAW_string = RAW_stringstream.str();    const char* RAW_Cstr = RAW_string.c_str();
59
+    ifstream RAW_infile;
60
+    RAW_infile.open(RAW_Cstr);
61
+    if (RAW_infile.fail()) {
62
+      cout << RAW_Cstr << endl;
63
+      JSCerror("Could not open RAW_infile... "); 
64
+    }
65
+
66
+    // We also read the f-sumrule file, to correct for missing intensity.
67
+    stringstream FSR_stringstream;    string FSR_string;
68
+    FSR_stringstream << prefix << ".fsr";
69
+    FSR_string = FSR_stringstream.str();    const char* FSR_Cstr = FSR_string.c_str();
70
+    ifstream FSR_infile;
71
+    FSR_infile.open(FSR_Cstr);
72
+    if (FSR_infile.fail()) {
73
+      cout << FSR_Cstr << endl;
74
+      JSCerror("Could not open FSR_infile... "); 
75
+    }
76
+
77
+    stringstream SFT_stringstream;    string SFT_string;
78
+    SFT_stringstream << prefix << ".tft";
79
+    SFT_string = SFT_stringstream.str();    const char* SFT_Cstr = SFT_string.c_str();
80
+    ofstream SFT_outfile;
81
+    SFT_outfile.open(SFT_Cstr);
82
+    if (SFT_outfile.fail()) JSCerror("Could not open TFT_outfile... "); 
83
+
84
+    // First compute the static structure factor from the RAW data:
85
+
86
+    Vect_DP TSF(0.0, Npts_t);
87
+
88
+    DP omega;
89
+    int iK;
90
+    DP FF;
91
+    //int conv;
92
+    DP dev;
93
+    string label;
94
+
95
+    // Now define time coordinates: between 0 and t_max
96
+    Vect_DP tlattice(Npts_t);
97
+    for (int i = 0; i < Npts_t; ++i) tlattice[i] = (i + 0.5) * t_max/Npts_t;
98
+
99
+    // Now the correlation at t:
100
+    Vect<complex<DP> > FT(0.0, Npts_t);
101
+    Vect_DP FTre(0.0, Npts_t);
102
+    Vect_DP FTim(0.0, Npts_t);
103
+
104
+    while (RAW_infile.peek() != EOF) {
105
+      RAW_infile >> omega >> iK >> FF >> dev >> label;
106
+      if (iK == 0) 
107
+	for (int it = 0; it < Npts_t; ++it) 
108
+	  FT[it] += FF * FF * exp(II * omega * tlattice[it]);
109
+      else 
110
+	for (int it = 0; it < Npts_t; ++it) 
111
+	  FT[it] += 2.0 * FF * FF * exp(II * omega * tlattice[it]);
112
+    }
113
+    RAW_infile.close();
114
+
115
+    // Reset proper normalization:
116
+    for (int it = 0; it < Npts_t; ++it) {
117
+      FTre[it] = real(FT[it]);
118
+      FTim[it] = imag(FT[it]);
119
+    }
120
+
121
+    // Output to file:
122
+    for (int it = 0; it < Npts_t; ++it) {
123
+      if (it > 0) SFT_outfile << endl;
124
+      SFT_outfile << tlattice[it] << "\t" << FTre[it] << "\t" << FTim[it];
125
+    }
126
+
127
+    SFT_outfile.close();
128
+  }
129
+
130
+  return(0);
131
+
132
+}

+ 118
- 0
src/EXECS/LiebLin_Fourier_to_t_equal_x_from_RAW.cc View File

@@ -0,0 +1,118 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_Fourier_to_t_equal_x.cc
10
+
11
+Purpose:  Fourier transform to static space correlator for LiebLin.
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 10) { // provide some info
24
+
25
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
26
+    cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
27
+    cout << endl << "Provide the following arguments:" << endl << endl;
28
+    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;
29
+    cout << "DP c_int \t\t Value of the interaction parameter" << endl;
30
+    cout << "DP L \t\t\t Length of the system" << endl;
31
+    cout << "int N \t\t\t Number of particles" << endl;
32
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
33
+    //cout << "DP kBT \t\t Temperature" << endl;
34
+    cout << "RAW file name" << endl;
35
+    cout << "int Npts_t \t Number of points in time for the Fourier transform" << endl;
36
+    cout << "DP t_max \t Max time to be used" << endl;
37
+  }
38
+
39
+  else { // (argc == 10), correct nr of arguments
40
+    char whichDSF = *argv[1];
41
+    DP c_int = atof(argv[2]);
42
+    DP L = atof(argv[3]);
43
+    int N = atoi(argv[4]);
44
+    int iKmin = atoi(argv[5]);
45
+    int iKmax = atoi(argv[6]);
46
+    //DP kBT = atof(argv[7]);
47
+    char* rawfilename = argv[7];
48
+    int Npts_t = atoi(argv[8]);
49
+    DP t_max = atof(argv[9]);
50
+
51
+    // Momentum business: use symmetry
52
+    if (iKmin != 0) JSCerror("LiebLin_Fourier_to_t_equal_x only implemented for raw files with iKmin == 0.");
53
+
54
+    ifstream RAW_infile;
55
+    //RAW_infile.open(RAW_Cstr);
56
+    RAW_infile.open(rawfilename);
57
+    if (RAW_infile.fail()) {
58
+      //cout << RAW_Cstr << endl;
59
+      cout << rawfilename << endl;
60
+      JSCerror("Could not open RAW_infile... "); 
61
+    }
62
+
63
+    stringstream SFT_stringstream;    string SFT_string;
64
+    SFT_stringstream << rawfilename << "_tft";
65
+    SFT_string = SFT_stringstream.str();    const char* SFT_Cstr = SFT_string.c_str();
66
+    ofstream SFT_outfile;
67
+    SFT_outfile.open(SFT_Cstr);
68
+    if (SFT_outfile.fail()) JSCerror("Could not open TFT_outfile... "); 
69
+
70
+    // First compute the static structure factor from the RAW data:
71
+
72
+    Vect_DP TSF(0.0, Npts_t);
73
+
74
+    DP omega;
75
+    int iK;
76
+    DP FF;
77
+    //int conv;
78
+    DP dev;
79
+    string label;
80
+
81
+    // Now define time coordinates: between 0 and t_max
82
+    Vect_DP tlattice(Npts_t);
83
+    for (int i = 0; i < Npts_t; ++i) tlattice[i] = (i + 0.5) * t_max/Npts_t;
84
+
85
+    // Now the correlation at t:
86
+    Vect<complex<DP> > FT(0.0, Npts_t);
87
+    Vect_DP FTre(0.0, Npts_t);
88
+    Vect_DP FTim(0.0, Npts_t);
89
+
90
+    while (RAW_infile.peek() != EOF) {
91
+      RAW_infile >> omega >> iK >> FF >> dev >> label;
92
+      if (iK == 0) 
93
+	for (int it = 0; it < Npts_t; ++it) 
94
+	  FT[it] += FF * FF * exp(II * omega * tlattice[it]);
95
+      else 
96
+	for (int it = 0; it < Npts_t; ++it) 
97
+	  FT[it] += 2.0 * FF * FF * exp(II * omega * tlattice[it]);
98
+    }
99
+    RAW_infile.close();
100
+
101
+    // Reset proper normalization:
102
+    for (int it = 0; it < Npts_t; ++it) {
103
+      FTre[it] = real(FT[it]);
104
+      FTim[it] = imag(FT[it]);
105
+    }
106
+
107
+    // Output to file:
108
+    for (int it = 0; it < Npts_t; ++it) {
109
+      if (it > 0) SFT_outfile << endl;
110
+      SFT_outfile << tlattice[it] << "\t" << FTre[it] << "\t" << FTim[it];
111
+    }
112
+
113
+    SFT_outfile.close();
114
+  }
115
+
116
+  return(0);
117
+
118
+}

+ 191
- 0
src/EXECS/LiebLin_Fourier_to_x_equal_t.cc View File

@@ -0,0 +1,191 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_Fourier_to_x_equal_t.cc
10
+
11
+Purpose:  Fourier transform to static space correlator for LiebLin.
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 9) { // provide some info
24
+
25
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
26
+    cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
27
+    cout << endl << "Provide the following arguments:" << endl << endl;
28
+    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;
29
+    cout << "DP c_int \t\t Value of the interaction parameter" << endl;
30
+    cout << "DP L \t\t\t Length of the system" << endl;
31
+    cout << "int N \t\t\t Number of particles" << endl;
32
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
33
+    cout << "DP kBT \t\t Temperature" << endl;
34
+    cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
35
+  }
36
+
37
+  else { // (argc == 9), correct nr of arguments
38
+    char whichDSF = *argv[1];
39
+    DP c_int = atof(argv[2]);
40
+    DP L = atof(argv[3]);
41
+    int N = atoi(argv[4]);
42
+    int iKmin = atoi(argv[5]);
43
+    int iKmax = atoi(argv[6]);
44
+    DP kBT = atof(argv[7]);
45
+    int Npts_x = atoi(argv[8]);
46
+    // Force Npts_x
47
+    //Npts_x = L;
48
+
49
+    stringstream filenameprefix;
50
+    Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
51
+    string prefix = filenameprefix.str();    
52
+
53
+    stringstream RAW_stringstream;    string RAW_string;
54
+    RAW_stringstream << prefix << ".raw";
55
+    RAW_string = RAW_stringstream.str();    const char* RAW_Cstr = RAW_string.c_str();
56
+    ifstream RAW_infile;
57
+    RAW_infile.open(RAW_Cstr);
58
+    if (RAW_infile.fail()) {
59
+      cout << RAW_Cstr << endl;
60
+      JSCerror("Could not open RAW_infile... "); 
61
+    }
62
+
63
+    // We also read the f-sumrule file, to correct for missing intensity.
64
+    stringstream FSR_stringstream;    string FSR_string;
65
+    FSR_stringstream << prefix << ".fsr";
66
+    FSR_string = FSR_stringstream.str();    const char* FSR_Cstr = FSR_string.c_str();
67
+    ifstream FSR_infile;
68
+    FSR_infile.open(FSR_Cstr);
69
+    if (FSR_infile.fail()) {
70
+      cout << FSR_Cstr << endl;
71
+      JSCerror("Could not open FSR_infile... "); 
72
+    }
73
+
74
+    stringstream SFT_stringstream;    string SFT_string;
75
+    SFT_stringstream << prefix << ".sft";
76
+    SFT_string = SFT_stringstream.str();    const char* SFT_Cstr = SFT_string.c_str();
77
+    ofstream SFT_outfile;
78
+    SFT_outfile.open(SFT_Cstr);
79
+    if (SFT_outfile.fail()) JSCerror("Could not open SFT_outfile... "); 
80
+
81
+    // First compute the static structure factor from the RAW data:
82
+
83
+    Vect_DP SSF(0.0, iKmax - iKmin + 1);
84
+
85
+    DP omega;
86
+    int iK;
87
+    DP FF;
88
+    //int conv;
89
+    DP dev;
90
+    string label;
91
+
92
+    while (RAW_infile.peek() != EOF) {
93
+      RAW_infile >> omega >> iK >> FF >> dev >> label;
94
+      if (iK >= iKmin && iK <= iKmax) {
95
+	SSF[iK - iKmin] += FF * FF;
96
+      }
97
+    }
98
+    RAW_infile.close();
99
+
100
+    // Reset proper normalization:
101
+    DP normalization = twoPI * L; 
102
+    for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) SSF[iK] *= normalization/twoPI; // twoPI from integral over omega
103
+
104
+    // We now refine the SSF in the following way.
105
+    // First, we read off the f-sumrule saturation from the FSR file.
106
+    // Then, we put back the missing weight, assuming that it lives
107
+    // on the free k^2 dispersion relation (so the DSF is then simply 2\pi N/L \delta(\omega - k^2)).
108
+
109
+    Vect_DP FSRsaturated(0.0, iKmax - iKmin + 1);
110
+    int dummyint;
111
+    DP dummy;
112
+    for (int i = iKmin; i <= iKmax; ++i)
113
+      FSR_infile >> dummyint >> FSRsaturated[i - iKmin] >> dummy;
114
+
115
+    FSR_infile.close();
116
+
117
+    // Now correct the SSF by the missing piece:
118
+    //for (int iK = iKmin; iK <= iKmax; ++iK)
119
+    //SSF[iK - iKmin] += (1.0 - FSRsaturated[iK - iKmin]) * N/L;
120
+
121
+    //cout << FSRsaturated << endl;
122
+
123
+    //cout << SSF << endl;
124
+
125
+    // Now define real-space coordinates: between 0 and L
126
+    Vect_DP xlattice(Npts_x);
127
+    for (int i = 0; i < Npts_x; ++i) xlattice[i] = (i + 0.5) * L/Npts_x;
128
+
129
+    // Now the correlation at x:
130
+    Vect_DP FTre(0.0, Npts_x);
131
+    Vect_DP FTim(0.0, Npts_x);
132
+
133
+    DP twopioverL = twoPI/L;
134
+
135
+    // Fourier transform:
136
+    for (int ix = 0; ix < Npts_x; ++ix) {
137
+      for (int iK = iKmin; iK <= iKmax; ++iK) {
138
+	FTre[ix] += SSF[iK - iKmin] * cos(twopioverL * iK * xlattice[ix]);
139
+	FTim[ix] += SSF[iK - iKmin] * sin(twopioverL * iK * xlattice[ix]);
140
+      }
141
+      // Reset proper normalization: 1/L from space FT,
142
+      FTre[ix] /= L;
143
+      FTim[ix] /= L;
144
+
145
+      // Outside of window iKmin, iKmax, we take the DSF to be a constant with delta function 
146
+      // at free energy k^2, so DSF = 2\pi N/L \delta(\omega - k^2) (to fit f-sumrule)
147
+      // so SSF becomes N/L.
148
+      // We thus need to correct above by adding
149
+      // \frac{1}{L} \sum_{-\infty}^{iKmin - 1} SSF e^{ikx} + \frac{1}{L} \sum_{iKmax + 1}^\infty SSF e^{ikx}
150
+      // Resumming carefully:
151
+      if (whichDSF == 'd') {
152
+	FTre[ix] += (sin(twopioverL * (iKmin - 0.5) * xlattice[ix]) - sin(twopioverL * (iKmax + 0.5) * xlattice[ix])) 
153
+	  * N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
154
+	FTim[ix] += (-cos(twopioverL * (iKmin - 0.5) * xlattice[ix]) + cos(twopioverL * (iKmax + 0.5) * xlattice[ix])) 
155
+	  * N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
156
+      }
157
+    }
158
+
159
+    // Since iKmax and iKmin are finite, we need to average over an interval of 
160
+    // deltax such that (2\pi/L) iKmax deltax = 2\pi, with deltax == deltaix * L/Npts_x
161
+    // so deltaix = (Npts_x/L) * (L/iKmax) 
162
+    /*
163
+    int deltaix = 0*int(Npts_x/(2.0*iKmax));
164
+    cout << "deltaix = " << deltaix << endl;
165
+
166
+    Vect_DP FTreavg(0.0, Npts_x);
167
+    Vect_DP FTimavg(0.0, Npts_x);
168
+    for (int ix = 0; ix < Npts_x; ++ix) {
169
+      for (int ix2 = -deltaix; ix2 < deltaix; ++ix2) {
170
+	FTreavg[ix] += FTre[JSC::min(JSC::max(0, ix + ix2), Npts_x - 1)];
171
+	FTimavg[ix] += FTim[JSC::min(JSC::max(0, ix + ix2), Npts_x - 1)];
172
+      }
173
+      FTreavg[ix] /= (2*deltaix + 1);
174
+      FTimavg[ix] /= (2*deltaix + 1);
175
+    }
176
+    */
177
+    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;
178
+
179
+    // Output to file:
180
+    for (int ix = 0; ix < Npts_x; ++ix) {
181
+      if (ix > 0) SFT_outfile << endl;
182
+      //SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix];
183
+      SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix];
184
+    }
185
+
186
+    SFT_outfile.close();
187
+  }
188
+
189
+  return(0);
190
+
191
+}

+ 147
- 0
src/EXECS/LiebLin_Fourier_to_x_equal_t_from_RAW.cc View File

@@ -0,0 +1,147 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_Fourier_to_x_equal_t.cc
10
+
11
+Purpose:  Fourier transform to static space correlator for LiebLin.
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 9) { // provide some info
24
+
25
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
26
+    cout << endl << "Usage of LiebLin_Fourier_to_x_equal_t executable: " << endl;
27
+    cout << endl << "Provide the following arguments:" << endl << endl;
28
+    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;
29
+    cout << "DP c_int \t\t Value of the interaction parameter" << endl;
30
+    cout << "DP L \t\t\t Length of the system" << endl;
31
+    cout << "int N \t\t\t Number of particles" << endl;
32
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers scanned over" << endl;
33
+    //cout << "DP kBT \t\t Temperature" << endl;
34
+    cout << "RAW file name" << endl;
35
+    cout << "int Npts_x Number of points in space for the Fourier transform" << endl;
36
+  }
37
+
38
+  else { // (argc == 9), correct nr of arguments
39
+    char whichDSF = *argv[1];
40
+    DP c_int = atof(argv[2]);
41
+    DP L = atof(argv[3]);
42
+    int N = atoi(argv[4]);
43
+    int iKmin = atoi(argv[5]);
44
+    int iKmax = atoi(argv[6]);
45
+    //DP kBT = atof(argv[7]);
46
+    char* rawfilename = argv[7];
47
+    int Npts_x = atoi(argv[8]);
48
+    // Force Npts_x
49
+    //Npts_x = L;
50
+
51
+    //stringstream filenameprefix;
52
+    //Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
53
+    //string prefix = filenameprefix.str();    
54
+
55
+    //stringstream RAW_stringstream;    string RAW_string;
56
+    //RAW_stringstream << prefix << ".raw";
57
+    //RAW_string = RAW_stringstream.str();    const char* RAW_Cstr = RAW_string.c_str();
58
+    ifstream RAW_infile;
59
+    //RAW_infile.open(RAW_Cstr);
60
+    RAW_infile.open(rawfilename);
61
+    if (RAW_infile.fail()) {
62
+      //cout << RAW_Cstr << endl;
63
+      cout << rawfilename << endl;
64
+      JSCerror("Could not open RAW_infile... "); 
65
+    }
66
+
67
+    // Define the output file name: use the RAW file name but with different suffix
68
+
69
+    stringstream SFT_stringstream;    string SFT_string;
70
+    SFT_stringstream << rawfilename << "_sft";
71
+    SFT_string = SFT_stringstream.str();    const char* SFT_Cstr = SFT_string.c_str();
72
+    ofstream SFT_outfile;
73
+    SFT_outfile.open(SFT_Cstr);
74
+    if (SFT_outfile.fail()) JSCerror("Could not open SFT_outfile... "); 
75
+
76
+    // First compute the static structure factor from the RAW data:
77
+
78
+    Vect_DP SSF(0.0, iKmax - iKmin + 1);
79
+
80
+    DP omega;
81
+    int iK;
82
+    DP FF;
83
+    //int conv;
84
+    DP dev;
85
+    string label;
86
+
87
+    while (RAW_infile.peek() != EOF) {
88
+      RAW_infile >> omega >> iK >> FF >> dev >> label;
89
+      if (iK >= iKmin && iK <= iKmax) {
90
+	SSF[iK - iKmin] += FF * FF;
91
+      }
92
+    }
93
+    RAW_infile.close();
94
+
95
+    // Reset proper normalization:
96
+    DP normalization = twoPI * L; 
97
+    for (int iK = 0; iK < iKmax - iKmin + 1; ++iK) SSF[iK] *= normalization/twoPI; // twoPI from integral over omega
98
+
99
+
100
+    // Now define real-space coordinates: between 0 and L
101
+    Vect_DP xlattice(Npts_x);
102
+    for (int i = 0; i < Npts_x; ++i) xlattice[i] = (i + 0.5) * L/Npts_x;
103
+
104
+    // Now the correlation at x:
105
+    Vect_DP FTre(0.0, Npts_x);
106
+    Vect_DP FTim(0.0, Npts_x);
107
+
108
+    DP twopioverL = twoPI/L;
109
+
110
+    // Fourier transform:
111
+    for (int ix = 0; ix < Npts_x; ++ix) {
112
+      for (int iK = iKmin; iK <= iKmax; ++iK) {
113
+	FTre[ix] += SSF[iK - iKmin] * cos(twopioverL * iK * xlattice[ix]);
114
+	FTim[ix] += SSF[iK - iKmin] * sin(twopioverL * iK * xlattice[ix]);
115
+      }
116
+      // Reset proper normalization: 1/L from space FT,
117
+      FTre[ix] /= L;
118
+      FTim[ix] /= L;
119
+
120
+      // Outside of window iKmin, iKmax, we take the DSF to be a constant with delta function 
121
+      // at free energy k^2, so DSF = 2\pi N/L \delta(\omega - k^2) (to fit f-sumrule)
122
+      // so SSF becomes N/L.
123
+      // We thus need to correct above by adding
124
+      // \frac{1}{L} \sum_{-\infty}^{iKmin - 1} SSF e^{ikx} + \frac{1}{L} \sum_{iKmax + 1}^\infty SSF e^{ikx}
125
+      // Resumming carefully:
126
+      //if (whichDSF == 'd') {
127
+      //FTre[ix] += (sin(twopioverL * (iKmin - 0.5) * xlattice[ix]) - sin(twopioverL * (iKmax + 0.5) * xlattice[ix])) 
128
+      //  * N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
129
+      //FTim[ix] += (-cos(twopioverL * (iKmin - 0.5) * xlattice[ix]) + cos(twopioverL * (iKmax + 0.5) * xlattice[ix])) 
130
+      //  * N/(2.0 * L*L * sin(PI * xlattice[ix]/L));
131
+      //}
132
+    }
133
+
134
+
135
+    // Output to file:
136
+    for (int ix = 0; ix < Npts_x; ++ix) {
137
+      if (ix > 0) SFT_outfile << endl;
138
+      //SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix] << "\t" << FTreavg[ix] << "\t" << FTimavg[ix];
139
+      SFT_outfile << xlattice[ix] << "\t" << FTre[ix] << "\t" << FTim[ix];
140
+    }
141
+
142
+    SFT_outfile.close();
143
+  }
144
+
145
+  return(0);
146
+
147
+}

+ 79
- 0
src/EXECS/LiebLin_Moses_tester.cc View File

@@ -0,0 +1,79 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_DSF_tester.cc
10
+
11
+Purpose:  allows for Ix2 manipulations (user-prompted) for LiebLin gas
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 8) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
27
+    cout << endl << "Usage of LiebLin_DSF_tester executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
31
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
32
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
33
+    cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
34
+    cout << "int DIl \t\t shift of left  sea as compared to its ground state position" << endl; 
35
+    cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl; 
36
+  }
37
+
38
+  else { // (argc == 6), correct nr of arguments
39
+    char whichDSF = *argv[1];
40
+    DP c_int = atof(argv[2]);
41
+    DP L = atof(argv[3]);
42
+    int N = atoi(argv[4]);
43
+    int Nl = atoi(argv[5]);
44
+    //int Nr = N - Nl;
45
+    int DIl = atoi(argv[6]);
46
+    int DIr = atoi(argv[7]);
47
+
48
+    if (whichDSF != 'd') JSCerror("Other options not implemented yet in LiebLin_Moses_tester");
49
+
50
+    // Define the Moses state:
51
+    LiebLin_Bethe_State MosesState (c_int, L, N);
52
+
53
+    // Split the sea:
54
+    for (int i = 0; i < Nl; ++i) MosesState.Ix2[i] -= 2 * DIl;
55
+    for (int i = Nl; i < N; ++i) MosesState.Ix2[i] += 2 * DIr;
56
+
57
+    MosesState.Compute_All (true);
58
+
59
+    LiebLin_Bethe_State estate = MosesState;
60
+    cout << MosesState;
61
+
62
+    int Ix2old, Ix2new;
63
+    int again = 0;
64
+    do {
65
+      cout << "Substitute Ix2:  which for which ?" << endl;
66
+      cin >> Ix2old >> Ix2new;
67
+      for (int i = 0; i < estate.N; ++i) if (estate.Ix2[i] == Ix2old) estate.Ix2[i] = Ix2new;
68
+      estate.Compute_All(false);
69
+      cout << estate;
70
+      cout << setprecision(16) << "omega = " << estate.E - MosesState.E << "\t" << exp(real(ln_Density_ME(MosesState, estate))) << endl;
71
+      cout << "Another try ? (0 == no)" << endl;
72
+      cin >> again;
73
+    } while (again != 0);
74
+
75
+  }
76
+
77
+  return(0);
78
+}
79
+

+ 134
- 0
src/EXECS/LiebLin_RAW_File_Stats.cc View File

@@ -0,0 +1,134 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_RAW_File_stats.cc
10
+
11
+Purpose:  Analyzes the distribution of matrix element values in a RAW file,
12
+          to help with optimization of the scanning procedure.
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+using namespace JSC;
20
+
21
+
22
+int main(int argc, char* argv[]) 
23
+{
24
+
25
+  if (argc != 9) { // provide some info
26
+
27
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
28
+    cout << endl << "Usage of LiebLin_RAW_File_Stats executable: " << endl;
29
+    cout << endl << "Provide the following arguments:" << endl << endl;
30
+    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;
31
+    cout << "DP c_int \t\t Value of the interaction parameter:  use positive real values only" << endl;
32
+    cout << "DP L \t\t\t Length of the system:  use positive real values only" << endl;
33
+    cout << "int N \t\t\t Number of particles:  use positive integer values only" << endl;
34
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  -2*N and 2*N" << endl;
35
+    cout << "DP kBT \t\t Temperature (positive only of course)" << endl;
36
+    cout << "int Aggregate size" << endl;
37
+  }
38
+
39
+  else { // (argc == 9), correct nr of arguments
40
+    char whichDSF = *argv[1];
41
+    DP c_int = atof(argv[2]);
42
+    DP L = atof(argv[3]);
43
+    int N = atoi(argv[4]);
44
+    int iKmin = atoi(argv[5]);
45
+    int iKmax = atoi(argv[6]);
46
+    DP kBT = atof(argv[7]);
47
+    int AgSize = atoi(argv[8]);
48
+
49
+    if (AgSize < 2) JSCerror("Give an aggregate size > 1 in LiebLin_RAW_File_Stats.");
50
+
51
+    stringstream RAW_stringstream;  string RAW_string;
52
+    Data_File_Name (RAW_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
53
+    RAW_stringstream << ".raw";
54
+    RAW_string = RAW_stringstream.str();    const char* RAW_Cstr = RAW_string.c_str();
55
+
56
+    ifstream RAW_infile;
57
+    RAW_infile.open(RAW_Cstr);
58
+    if (RAW_infile.fail()) {
59
+      cout << RAW_Cstr << endl;
60
+      JSCerror("Could not open RAW_infile... "); 
61
+    }
62
+
63
+    stringstream STAT_stringstream;  string STAT_string;
64
+    Data_File_Name (STAT_stringstream, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
65
+    STAT_stringstream << ".stat";
66
+    STAT_string = STAT_stringstream.str();    const char* STAT_Cstr = STAT_string.c_str();
67
+
68
+    ofstream STATfile;
69
+    STATfile.open(STAT_Cstr);    
70
+    if (STATfile.fail()) {
71
+      cout << STAT_Cstr << endl; JSCerror("Could not open STATfile.");
72
+    }
73
+
74
+    LiebLin_Bethe_State AveragingState = Canonical_Saddle_Point_State (c_int, L, N, whichDSF == 'Z' ? 0.0 : kBT);
75
+
76
+    DP Chem_Pot = Chemical_Potential (AveragingState);
77
+    //DP sumrule_factor = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, fixed_iK, iKneeded);
78
+    Vect<DP> sumrule_factor(iKmax - iKmin + 1);
79
+    for (int ik = 0; ik < iKmax - iKmin + 1; ++ik) 
80
+      sumrule_factor[ik] = Sumrule_Factor (whichDSF, AveragingState, Chem_Pot, ik, ik);
81
+    // Normalize by total number of considered momenta
82
+    DP correction_factor = 1.0/(iKmax - iKmin + 1);
83
+    if (iKmin <= 0 && iKmax >= 0 && whichDSF == 'd') { // correct for fact that RhoRho is 0 at k = 0
84
+      sumrule_factor[0] = 0.0;
85
+      correction_factor = 1.0/(iKmax - iKmin);
86
+    }
87
+
88
+    for (int ik = 0; ik < iKmax - iKmin + 1; ++ik) sumrule_factor[ik] *= correction_factor;
89
+
90
+    DP omega;
91
+    int iK;
92
+    DP ME;
93
+    DP dev;
94
+    string label;
95
+    
96
+    int nread = 0;
97
+
98
+    DP srcont = 0.0;
99
+    DP abssrcont = 0.0;
100
+    DP maxsrcont = 0.0;
101
+    DP totsrcont = 0.0;
102
+    DP accumulatedsrcont = 0.0;
103
+    int naccounted = 0;
104
+
105
+    while (RAW_infile.peek() != EOF) {
106
+
107
+      RAW_infile >> omega >> iK >> ME >> dev >> label;
108
+      nread++;
109
+      
110
+      if (iK >= iKmin && iK <= iKmax) {
111
+	srcont = omega * ME * ME * sumrule_factor[iK - iKmin];
112
+	abssrcont = fabs(srcont);
113
+	maxsrcont = JSC::max(maxsrcont, abssrcont);
114
+	totsrcont += srcont;
115
+	accumulatedsrcont += srcont;
116
+	naccounted++;
117
+      }
118
+
119
+      if (naccounted >= AgSize) {
120
+	STATfile << nread << "\t" << maxsrcont << "\t" << totsrcont/AgSize << "\t" << totsrcont/(AgSize * (maxsrcont > 0.0 ? maxsrcont : 1.0)) << "\t" << accumulatedsrcont << endl;
121
+	naccounted = 0;
122
+	maxsrcont = 0.0;
123
+	totsrcont = 0.0;
124
+      }
125
+    }
126
+    
127
+    RAW_infile.close();
128
+    STATfile.close();
129
+  }
130
+
131
+
132
+  return(0);
133
+}
134
+

+ 45
- 0
src/EXECS/LiebLin_TBA.cc View File

@@ -0,0 +1,45 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_TBA.cc
10
+
11
+Purpose:  solves the TBA equations for Lieb-Liniger
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+using namespace JSC;
20
+
21
+int main(int argc, const char* argv[])
22
+{
23
+
24
+  //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).");
25
+  if (argc != 6) JSCerror("Wrong number of arguments.  Use c(best to set to 1), mu, kBT, req_diff, Max_Secs");
26
+
27
+  DP c_int = atof(argv[1]);
28
+  DP mu = atof(argv[2]);
29
+  DP kBT = atof(argv[3]);
30
+  DP req_diff = atof(argv[4]);
31
+  int Max_Secs = atoi(argv[5]);
32
+
33
+  if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
34
+  if (kBT <= 0.0) JSCerror("Negative T ?  Not for the LiebLin gas.");
35
+  if (Max_Secs < 10) JSCerror("Give more time.");
36
+
37
+  //cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
38
+
39
+  LiebLin_TBA_Solution  solution(c_int, mu, kBT, req_diff, Max_Secs);
40
+
41
+
42
+  cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
43
+
44
+  return(0);
45
+}

+ 44
- 0
src/EXECS/LiebLin_TBA_fixed_nbar.cc View File

@@ -0,0 +1,44 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_TBA_fixed_nbar.cc
10
+
11
+Purpose:  solves the TBA equations for Lieb-Liniger
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+using namespace JSC;
20
+
21
+int main(int argc, const char* argv[])
22
+{
23
+
24
+  //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).");
25
+  if (argc != 6) JSCerror("Wrong number of arguments.  Use c(best to set to 1), nbar, kBT, req_diff, Max_Secs");
26
+
27
+  DP c_int = atof(argv[1]);
28
+  DP nbar = atof(argv[2]);
29
+  DP kBT = atof(argv[3]);
30
+  DP req_diff = atof(argv[4]);
31
+  int Max_Secs = atoi(argv[5]);
32
+
33
+  if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
34
+  if (kBT <= 0.0) JSCerror("Negative T ?  Not for the LiebLin gas.");
35
+  if (Max_Secs < 10) JSCerror("Give more time.");
36
+
37
+  //cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
38
+
39
+  LiebLin_TBA_Solution solution = LiebLin_TBA_Solution_fixed_nbar (c_int, nbar, kBT, req_diff, Max_Secs);
40
+
41
+  cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
42
+
43
+  return(0);
44
+}

+ 43
- 0
src/EXECS/LiebLin_TBA_fixed_nbar_ebar.cc View File

@@ -0,0 +1,43 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  LiebLin_TBA_fixed_nbar_ebar.cc
10
+
11
+Purpose:  solves the TBA equations for Lieb-Liniger
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+using namespace JSC;
20
+
21
+int main(int argc, const char* argv[])
22
+{
23
+
24
+  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).");
25
+
26
+  DP c_int = atof(argv[1]);
27
+  DP nbar = atof(argv[2]);
28
+  DP ebar = atof(argv[3]);
29
+  DP req_diff = atof(argv[4]);
30
+  int Max_Secs = atoi(argv[5]);
31
+  bool Save_data = bool(atoi(argv[6]));
32
+
33
+  if (c_int <= 0.0) JSCerror("Give a strictly positive c.");
34
+  if (Max_Secs < 10) JSCerror("Give more time.");
35
+
36
+  //cout << "Read c_int = " << c_int << "\tmu = " << mu << "\tOmega = " << Omega << "\tkBT = " << kBT << "\tMax_Secs = " << Max_Secs << endl;
37
+
38
+  LiebLin_TBA_Solution solution = LiebLin_TBA_Solution_fixed_nbar_ebar(c_int, nbar, ebar, req_diff, Max_Secs);
39
+
40
+  cout << solution.nbar << "\t" << solution.ebar << "\t" << solution.sbar << "\t";
41
+
42
+  return(0);
43
+}

+ 60
- 0
src/EXECS/ODSLF_DSF.cc View File

@@ -0,0 +1,60 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  ODSLF_DSF.cc
10
+
11
+Purpose:  main function for ABACUS++ for spinless fermions related to Heisenberg spin-1/2 chain
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+
24
+  if (argc != 10) { // provide some info
25
+
26
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
27
+    cout << "Usage of ODSLF_DSF executable: " << endl;
28
+    cout << endl << "Provide the following arguments:" << endl << endl;
29
+    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;
30
+    cout << "DP Delta \t\t Value of the anisotropy:  use positive real values only" << endl;
31
+    cout << "int N \t\t\t Length (number of sites) of the system:  use positive even integer values only" << endl;
32
+    cout << "int M \t\t\t Number of down spins:  use positive integer values between 1 and N/2" << endl;
33
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers to scan over:  recommended values:  0 and N" << endl;
34
+    cout << "int Max_Secs \t\t Allowed computational time:  (in seconds)" << endl;
35
+    cout << "DP target_sumrule \t sumrule saturation you're satisfied with" << endl;
36
+    cout << "bool refine \t\t Is this a refinement of a earlier calculations ?  (0 == false, 1 == true)" << endl;
37
+    cout << endl << "EXAMPLE: " << endl << endl;
38
+    cout << "ODSLF_DSF z 1.0 100 40 0 100 600 1.0 0" << endl << endl;
39
+  }
40
+
41
+  else if (argc == 10) { // !fixed_iK
42
+    char whichDSF = *argv[1];
43
+    DP Delta = atof(argv[2]);
44
+    int N = atoi(argv[3]);
45
+    int M = atoi(argv[4]);
46
+    int iKmin = atoi(argv[5]);
47
+    int iKmax = atoi(argv[6]);
48
+    int Max_Secs = atoi(argv[7]);
49
+    DP target_sumrule = atof(argv[8]);
50
+    bool refine = (atoi(argv[9]) == 1);
51
+
52
+    Scan_ODSLF (whichDSF, Delta, N, M, iKmin, iKmax, Max_Secs, target_sumrule, refine, 0, 1);
53
+  }
54
+
55
+
56
+  else JSCerror("Wrong number of arguments to ODSLF_DSF executable.");
57
+
58
+  return(0);
59
+}
60
+

+ 37
- 0
src/EXECS/Produce_Sorted_RAW_File.cc View File

@@ -0,0 +1,37 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Sort_RAW_File.cc
10
+
11
+Purpose:  produce a sorted .raw file.
12
+          
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 4) { 
24
+    cout << "Arguments needed: rawfile, whichDSF, whichsorting." << endl;
25
+    JSCerror("");
26
+  }
27
+
28
+  const char* rawfilename = argv[1];
29
+  char whichDSF = *argv[2];
30
+  char whichsorting = *argv[3];
31
+
32
+
33
+  //cout << rawfilename << "\t" << whichDSF << "\t" << whichsorting << endl;
34
+  Sort_RAW_File (rawfilename, whichsorting, whichDSF);
35
+
36
+  return(0);
37
+}

+ 99
- 0
src/EXECS/RAW_File_Stats.cc View File

@@ -0,0 +1,99 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  RAW_File_stats.cc
10
+
11
+Purpose:  Analyzes the distribution of matrix element values in a RAW file,
12
+          to help with optimization of the scanning procedure.
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+using namespace JSC;
20
+
21
+
22
+int main(int argc, char* argv[]) 
23
+{
24
+
25
+  if (argc != 3) { // provide some info
26
+
27
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
28
+    cout << endl << "Usage of RAW_File_Stats executable: " << endl;
29
+    cout << endl << "Provide the following arguments:" << endl << endl;
30
+    cout << endl << "string RAW file name" << endl;
31
+    cout << "int Aggregate size" << endl;
32
+  }
33
+
34
+  else { // correct nr of arguments
35
+    const char* rawfilename = argv[1];
36
+    int AgSize = atoi(argv[2]);
37
+
38
+    if (AgSize < 2) JSCerror("Give an aggregate size > 1 in LiebLin_RAW_File_Stats.");
39
+
40
+    ifstream RAW_infile;
41
+    RAW_infile.open(rawfilename);
42
+    if (RAW_infile.fail()) {
43
+      cout << rawfilename << endl;
44
+      JSCerror("Could not open RAW_infile... "); 
45
+    }
46
+
47
+    stringstream STAT_stringstream;  string STAT_string;
48
+    STAT_stringstream << rawfilename << "_AgS_" << AgSize << "_stat";
49
+    STAT_string = STAT_stringstream.str();    const char* STAT_Cstr = STAT_string.c_str();
50
+
51
+    ofstream STATfile;
52
+    STATfile.open(STAT_Cstr);    
53
+    if (STATfile.fail()) {
54
+      cout << STAT_Cstr << endl; JSCerror("Could not open STATfile.");
55
+    }
56
+
57
+    DP omega;
58
+    int iK;
59
+    DP ME;
60
+    DP dev;
61
+    string label;
62
+    
63
+    int nread = 0;
64
+
65
+    DP srcont = 0.0;
66
+    DP abssrcont = 0.0;
67
+    DP maxsrcont = 0.0;
68
+    DP totsrcont = 0.0;
69
+    DP accumulatedsrcont = 0.0;
70
+    int naccounted = 0;
71
+
72
+    while (RAW_infile.peek() != EOF) {
73
+
74
+      RAW_infile >> omega >> iK >> ME >> dev >> label;
75
+      nread++;
76
+      
77
+      srcont = ME * ME;
78
+      abssrcont = fabs(srcont);
79
+      maxsrcont = JSC::max(maxsrcont, abssrcont);
80
+      totsrcont += srcont;
81
+      accumulatedsrcont += srcont;
82
+      naccounted++;
83
+
84
+      if (naccounted >= AgSize) {
85
+	STATfile << nread << "\t" << maxsrcont << "\t" << totsrcont/AgSize << "\t" << totsrcont/(AgSize * (maxsrcont > 0.0 ? maxsrcont : 1.0)) << "\t" << accumulatedsrcont << endl;
86
+	naccounted = 0;
87
+	maxsrcont = 0.0;
88
+	totsrcont = 0.0;
89
+      }
90
+    }
91
+    
92
+    RAW_infile.close();
93
+    STATfile.close();
94
+  }
95
+
96
+
97
+  return(0);
98
+}
99
+

+ 90
- 0
src/EXECS/Smoothen_Heis_DSF.cc View File

@@ -0,0 +1,90 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Smoothen_Heis_DSF.cc
10
+
11
+Purpose:  produces .dsf and .ssf files from a .raw file
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 13 && argc != 14) { // Print out instructions
24
+    //if (strcmp(argv[1],"help") == 0) { // Output some instructions
25
+    cout << "Usage of Smoothen_Heis_DSF executable: " << endl << endl;
26
+    cout << "Provide arguments using one of the following options:" << endl << endl;
27
+    cout << "1) (for general momenta) whichDSF Delta N M iKmin iKmax DiK kBT ommin ommax Nom gwidth" << endl << endl;
28
+    cout << "2) (for fixed momentum) whichDSF Delta N M iKneeded ommin ommax Nom gwidth" << endl << endl;
29
+    //else JSCerror("Incomprehensible arguments in Smoothen_Heis_DSF executable.");
30
+  }
31
+
32
+  else if (argc == 13) { // !fixed_iK
33
+    char whichDSF = *argv[1];
34
+    DP Delta = atof(argv[2]);
35
+    int N = atoi(argv[3]);
36
+    int M = atoi(argv[4]);
37
+    int iKmin = atoi(argv[5]);
38
+    int iKmax = atoi(argv[6]);
39
+    int DiK = atoi(argv[7]);
40
+    DP kBT = atof(argv[8]);
41
+    DP ommin = atof(argv[9]);
42
+    DP ommax = atof(argv[10]);
43
+    int Nom = atoi(argv[11]);
44
+    DP gwidth = atof(argv[12]);
45
+
46
+    stringstream filenameprefix;
47
+    Data_File_Name (filenameprefix, whichDSF, Delta, N, M, iKmin, iKmax, kBT, 0, "");
48
+    string prefix = filenameprefix.str();    
49
+
50
+    DP normalization = twoPI;
51
+    DP denom_sum_K = 1.0/N;
52
+
53
+    Write_K_File (N, iKmin, iKmax);
54
+    Write_Omega_File (Nom, ommin, ommax);
55
+
56
+    DP sumcheck;
57
+    sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, gwidth, normalization, denom_sum_K);
58
+
59
+  }
60
+
61
+  /*
62
+  else if (argc == 10) { // fixed_iK
63
+    char whichDSF = *argv[1];
64
+    DP Delta = atof(argv[2]);
65
+    int N = atoi(argv[3]);
66
+    int M = atoi(argv[4]);
67
+    int iKneeded = atoi(argv[5]);
68
+    DP ommin = atof(argv[6]);
69
+    DP ommax = atof(argv[7]);
70
+    int Nom = atoi(argv[8]);
71
+    DP gwidth = atof(argv[9]);
72
+
73
+    bool fixed_iK = true;
74
+
75
+    stringstream filenameprefix;
76
+    Data_File_Name (filenameprefix, whichDSF, Delta, N, M, fixed_iK, iKneeded, 0.0, 0, "");
77
+    string prefix = filenameprefix.str();    
78
+
79
+    DP normalization = twoPI;
80
+    int iKmin = iKneeded;
81
+    int iKmax = iKneeded;
82
+
83
+    cout << "Smoothing:  sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
84
+  }
85
+  */
86
+
87
+  //else JSCerror("Wrong number of arguments to Smoothen_Heis_DSF executable.");
88
+
89
+  return(0);
90
+}

+ 111
- 0
src/EXECS/Smoothen_LiebLin_DSF.cc View File

@@ -0,0 +1,111 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Smoothen_LiebLin_DSF.cc
10
+
11
+Purpose:  produces .dsf and .ssf files from a .raw file
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 13) { // Print out instructions
24
+
25
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
26
+    cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl;
27
+    cout << endl << "Provide the following arguments:" << endl << endl;
28
+    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;
29
+    cout << "DP c_int \t\t Value of the interaction parameter" << endl;
30
+    cout << "DP L \t\t\t Length of the system" << endl;
31
+    cout << "int N \t\t\t Number of particles" << endl;
32
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
33
+    cout << "DP kBT \t\t Temperature" << endl;
34
+    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;
35
+    cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
36
+    cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
37
+    cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
38
+
39
+    cout << endl << "EXAMPLE: " << endl << endl;
40
+    cout << "Smoothen_LiebLin_DSF d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
41
+
42
+  }
43
+
44
+  else if (argc == 13) { // !fixed_iK
45
+    char whichDSF = *argv[1];
46
+    DP c_int = atof(argv[2]);
47
+    DP L = atof(argv[3]);
48
+    int N = atoi(argv[4]);
49
+    int iKmin = atoi(argv[5]);
50
+    int iKmax = atoi(argv[6]);
51
+    DP kBT = atof(argv[7]);
52
+    int DiK = atoi(argv[8]);
53
+    DP ommin = atof(argv[9]);
54
+    DP ommax = atof(argv[10]);
55
+    int Nom = atoi(argv[11]);
56
+    DP width = atof(argv[12]);
57
+
58
+    stringstream filenameprefix;
59
+    //void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
60
+    Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
61
+    string prefix = filenameprefix.str();    
62
+
63
+    DP normalization = twoPI * L;
64
+    DP denom_sum_K = L;
65
+
66
+    Write_K_File (L, iKmin, iKmax);
67
+    Write_Omega_File (Nom, ommin, ommax);
68
+    //cout << "Smoothing:  sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
69
+    // We use the scaled width function as default:
70
+
71
+    DP sumcheck;
72
+    //if (kBT < 0.1) 
73
+    //sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
74
+    sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
75
+      //else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
76
+    //cout << "Smoothing:  sumcheck = " << sumcheck << endl;
77
+  }
78
+
79
+  /*
80
+  else if (argc == 11) { // fixed_iK
81
+    char whichDSF = *argv[1];
82
+    DP c_int = atof(argv[2]);
83
+    DP L = atof(argv[3]);
84
+    int N = atoi(argv[4]);
85
+    int iK_UL = atoi(argv[5]);
86
+    int iKneeded = atoi(argv[6]);
87
+    DP ommin = atof(argv[7]);
88
+    DP ommax = atof(argv[8]);
89
+    int Nom = atoi(argv[9]);
90
+    DP gwidth = atof(argv[10]);
91
+    
92
+    //bool fixed_iK = true;
93
+    //LiebLin_Bethe_State GroundState (c_int, L, N, iK_UL, 0LL);  
94
+    stringstream filenameprefix;
95
+    //Data_File_Name (filenameprefix, whichDSF, fixed_iK, iKneeded, GroundState, GroundState);  
96
+    //Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 0.0);
97
+    Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, iKneeded, iKneeded, 0.0);
98
+    string prefix = filenameprefix.str();    
99
+
100
+    DP normalization = twoPI * L;
101
+    int iKmin = iKneeded;
102
+    int iKmax = iKneeded;
103
+
104
+    cout << "Smoothing:  sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
105
+  }
106
+  */
107
+
108
+  //else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
109
+
110
+  return(0);
111
+}

+ 120
- 0
src/EXECS/Smoothen_LiebLin_DSF_GeneralState.cc View File

@@ -0,0 +1,120 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Smoothen_LiebLin_DSF_GeneralState.cc
10
+
11
+Purpose:  produces .dsf and .ssf files from a .raw file
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 13) { // Print out instructions
24
+
25
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
26
+    cout << endl << "Usage of Smoothen_LiebLin_DSF executable: " << endl;
27
+    cout << endl << "Provide the following arguments:" << endl << endl;
28
+    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;
29
+    cout << "DP c_int \t\t Value of the interaction parameter" << endl;
30
+    cout << "DP L \t\t\t Length of the system" << endl;
31
+    cout << "int N \t\t\t Number of particles" << endl;
32
+    cout << "char* defaultScanStatename:\t\t file [].Ix2 contains the quantum numbers defining the AveragingState; used as defaultScanStatename" << endl;
33
+     cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
34
+    //cout << "DP kBT \t\t Temperature" << endl;
35
+    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;
36
+    cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
37
+    cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
38
+    cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
39
+
40
+    cout << endl << "EXAMPLE: " << endl << endl;
41
+    cout << "Smoothen_LiebLin_DSF d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
42
+
43
+  }
44
+
45
+  else if (argc == 13) { // !fixed_iK
46
+    int n = 1;
47
+    char whichDSF = *argv[n++];
48
+    DP c_int = atof(argv[n++]);
49
+    DP L = atof(argv[n++]);
50
+    int N = atoi(argv[n++]);
51
+    char* Ix2filenameprefix = argv[n++];
52
+    int iKmin = atoi(argv[n++]);
53
+    int iKmax = atoi(argv[n++]);
54
+    //DP kBT = atof(argv[7]);
55
+    DP kBT = 0.0;
56
+    int DiK = atoi(argv[n++]);
57
+    DP ommin = atof(argv[n++]);
58
+    DP ommax = atof(argv[n++]);
59
+    int Nom = atoi(argv[n++]);
60
+    DP width = atof(argv[n++]);
61
+
62
+    stringstream filenamestrstream;
63
+    filenamestrstream << Ix2filenameprefix;
64
+    string defaultScanStatename = filenamestrstream.str();
65
+
66
+    stringstream filenameprefix;
67
+    //void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
68
+    //Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
69
+    Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, defaultScanStatename);
70
+    string prefix = filenameprefix.str();    
71
+
72
+    DP normalization = twoPI * L;
73
+    DP denom_sum_K = L;
74
+
75
+    Write_K_File (L, iKmin, iKmax);
76
+    Write_Omega_File (Nom, ommin, ommax);
77
+    //cout << "Smoothing:  sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
78
+    // We use the scaled width function as default:
79
+
80
+    DP sumcheck;
81
+    //if (kBT < 0.1) 
82
+    //sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
83
+    sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
84
+      //else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
85
+    //cout << "Smoothing:  sumcheck = " << sumcheck << endl;
86
+  }
87
+
88
+  /*
89
+  else if (argc == 11) { // fixed_iK
90
+    char whichDSF = *argv[1];
91
+    DP c_int = atof(argv[2]);
92
+    DP L = atof(argv[3]);
93
+    int N = atoi(argv[4]);
94
+    int iK_UL = atoi(argv[5]);
95
+    int iKneeded = atoi(argv[6]);
96
+    DP ommin = atof(argv[7]);
97
+    DP ommax = atof(argv[8]);
98
+    int Nom = atoi(argv[9]);
99
+    DP gwidth = atof(argv[10]);
100
+    
101
+    //bool fixed_iK = true;
102
+    //LiebLin_Bethe_State GroundState (c_int, L, N, iK_UL, 0LL);  
103
+    stringstream filenameprefix;
104
+    //Data_File_Name (filenameprefix, whichDSF, fixed_iK, iKneeded, GroundState, GroundState);  
105
+    //Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, fixed_iK, iKneeded, 0.0);
106
+    Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iK_UL, iKneeded, iKneeded, 0.0);
107
+    string prefix = filenameprefix.str();    
108
+
109
+    DP normalization = twoPI * L;
110
+    int iKmin = iKneeded;
111
+    int iKmax = iKneeded;
112
+
113
+    cout << "Smoothing:  sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
114
+  }
115
+  */
116
+
117
+  //else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
118
+
119
+  return(0);
120
+}

+ 97
- 0
src/EXECS/Smoothen_LiebLin_DSF_MosesState.cc View File

@@ -0,0 +1,97 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Smoothen_LiebLin_DSF_MosesState.cc
10
+
11
+Purpose:  produces .dsf and .ssf files from a .raw file
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 15) { // Print out instructions
24
+
25
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
26
+    cout << endl << "Usage of Smoothen_LiebLin_DSF_MosesState executable: " << endl;
27
+    cout << endl << "Provide the following arguments:" << endl << endl;
28
+    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;
29
+    cout << "DP c_int \t\t Value of the interaction parameter" << endl;
30
+    cout << "DP L \t\t\t Length of the system" << endl;
31
+    cout << "int N \t\t\t Number of particles" << endl;
32
+    cout << "int Nl \t\t\t Number of particles in left Fermi sea (Nr is then N - Nl)" << endl;
33
+    cout << "int DIl \t\t shift of left  sea as compared to its ground state position" << endl; 
34
+    cout << "int DIr \t\t shift of right sea as compared to its ground state position" << endl; 
35
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
36
+    //cout << "DP kBT \t\t Temperature" << endl;
37
+    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;
38
+    cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
39
+    cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
40
+    cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
41
+
42
+    cout << endl << "EXAMPLE: " << endl << endl;
43
+    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;
44
+
45
+  }
46
+
47
+  else if (argc == 15) { // !fixed_iK
48
+    char whichDSF = *argv[1];
49
+    DP c_int = atof(argv[2]);
50
+    DP L = atof(argv[3]);
51
+    int N = atoi(argv[4]);
52
+    int Nl = atoi(argv[5]);
53
+    //int Nr = N - Nl;
54
+    int DIl = atoi(argv[6]);
55
+    int DIr = atoi(argv[7]);
56
+    int iKmin = atoi(argv[8]);
57
+    int iKmax = atoi(argv[9]);
58
+    //DP kBT = atof(argv[10]);
59
+    DP kBT = 0.0;
60
+    int DiK = atoi(argv[10]);
61
+    DP ommin = atof(argv[11]);
62
+    DP ommax = atof(argv[12]);
63
+    int Nom = atoi(argv[13]);
64
+    DP width = atof(argv[14]);
65
+
66
+    // Handy default name:
67
+    stringstream defaultScanStatename_strstream;
68
+    defaultScanStatename_strstream << "Moses_Nl_" << Nl << "_DIl_" << DIl << "_DIr_" << DIr;
69
+    string defaultScanStatename = defaultScanStatename_strstream.str();
70
+
71
+    stringstream filenameprefix;
72
+    //void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
73
+    Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, defaultScanStatename);
74
+    string prefix = filenameprefix.str();    
75
+
76
+
77
+
78
+    DP normalization = twoPI * L;
79
+    DP denom_sum_K = L;
80
+
81
+    Write_K_File (L, iKmin, iKmax);
82
+    Write_Omega_File (Nom, ommin, ommax);
83
+    //cout << "Smoothing:  sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
84
+    // We use the scaled width function as default:
85
+
86
+    DP sumcheck;
87
+    //if (kBT < 0.1) 
88
+    //sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
89
+    sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
90
+      //else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
91
+    //cout << "Smoothing:  sumcheck = " << sumcheck << endl;
92
+  }
93
+
94
+  //else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
95
+
96
+  return(0);
97
+}

+ 82
- 0
src/EXECS/Smoothen_LiebLin_DSF_Scaled.cc View File

@@ -0,0 +1,82 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Smoothen_LiebLin_DSF_Scaled.cc
10
+
11
+Purpose:  produces .dsfs and .ssf files from a .raw file
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 13) { // Print out instructions
24
+
25
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
26
+    cout << endl << "Usage of Smoothen_LiebLin_DSF_Scaled executable: " << endl;
27
+    cout << endl << "Provide the following arguments:" << endl << endl;
28
+    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;
29
+    cout << "DP c_int \t\t Value of the interaction parameter" << endl;
30
+    cout << "DP L \t\t\t Length of the system" << endl;
31
+    cout << "int N \t\t\t Number of particles" << endl;
32
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
33
+    cout << "DP kBT \t\t Temperature" << endl;
34
+    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;
35
+    cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
36
+    cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
37
+    cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
38
+
39
+    cout << endl << "EXAMPLE: " << endl << endl;
40
+    cout << "Smoothen_LiebLin_DSF d 1.0 100.0 100 0 200 5.0 1 0.0 10.0 500 2.0" << endl << endl;
41
+
42
+  }
43
+
44
+  else if (argc == 13) { // !fixed_iK
45
+    char whichDSF = *argv[1];
46
+    DP c_int = atof(argv[2]);
47
+    DP L = atof(argv[3]);
48
+    int N = atoi(argv[4]);
49
+    int iKmin = atoi(argv[5]);
50
+    int iKmax = atoi(argv[6]);
51
+    DP kBT = atof(argv[7]);
52
+    int DiK = atoi(argv[8]);
53
+    DP ommin = atof(argv[9]);
54
+    DP ommax = atof(argv[10]);
55
+    int Nom = atoi(argv[11]);
56
+    DP width = atof(argv[12]);
57
+
58
+    stringstream filenameprefix;
59
+    //void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
60
+    Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
61
+    string prefix = filenameprefix.str();    
62
+
63
+    DP normalization = twoPI * L;
64
+    //DP denom_sum_K = L;
65
+
66
+    Write_K_File (L, iKmin, iKmax);
67
+    Write_Omega_File (Nom, ommin, ommax);
68
+    //cout << "Smoothing:  sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization) << endl;
69
+    // We use the scaled width function as default:
70
+
71
+    DP sumcheck;
72
+    //if (kBT < 0.1) 
73
+    sumcheck = Smoothen_RAW_into_SF_LiebLin_Scaled (prefix, L, N, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization);
74
+    //sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, DiK, ommin, ommax, Nom, width, normalization, denom_sum_K);
75
+      //else sumcheck = Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, width, normalization);
76
+    //cout << "Smoothing:  sumcheck = " << sumcheck << endl;
77
+  }
78
+
79
+  //else JSCerror("Wrong number of arguments to Smoothen_LiebLin_DSF executable.");
80
+
81
+  return(0);
82
+}

+ 103
- 0
src/EXECS/Smoothen_LiebLin_DSF_over_Ensemble.cc View File

@@ -0,0 +1,103 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS library.
4
+
5
+Copyright (c).
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Smoothen_LiebLin_DSF_over_Ensemble.cc
10
+
11
+Purpose:  produces .dsf and .ssf files from an ensemble of .raw files
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 13) { // Print out instructions
24
+
25
+    cout << endl << "Welcome to ABACUS++\t(copyright J.-S. Caux)." << endl;
26
+    cout << endl << "Usage of Smoothen_LiebLin_DSF_over_Ensemble executable: " << endl;
27
+    cout << endl << "Provide the following arguments:" << endl << endl;
28
+    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;
29
+    cout << "DP c_int \t\t Value of the interaction parameter" << endl;
30
+    cout << "DP L \t\t\t Length of the system" << endl;
31
+    cout << "int N \t\t\t Number of particles" << endl;
32
+    cout << "int iKmin" << endl << "int iKmax \t\t Min and max momentum integers" << endl;
33
+    cout << "DP kBT \t\t Temperature" << endl;
34
+    //cout << "int nstates \t\t\t Number of states considered in the ensemble" << endl;
35
+    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;
36
+    cout << "DP ommin" << endl << "DP ommax \t\t Min and max frequencies to cover in smoothened DSF" << endl;
37
+    cout << "Nom \t\t\t Number of frequency points used for discretization" << endl;
38
+    cout << "DP width \t\t Gaussian width used in smoothing, in units of two-particle level spacing" << endl;
39
+
40
+    cout << endl << "EXAMPLE: " << endl << endl;
41
+    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;
42
+
43
+  }
44
+
45
+  else if (argc == 13) { 
46
+    char whichDSF = *argv[1];
47
+    DP c_int = atof(argv[2]);
48
+    DP L = atof(argv[3]);
49
+    int N = atoi(argv[4]);
50
+    int iKmin = atoi(argv[5]);
51
+    int iKmax = atoi(argv[6]);
52
+    DP kBT = atof(argv[7]);
53
+    //int nstates_req = atoi(argv[8]);
54
+    int DiK = atoi(argv[8]);
55
+    DP ommin = atof(argv[9]);
56
+    DP ommax = atof(argv[10]);
57
+    int Nom = atoi(argv[11]);
58
+    DP width = atof(argv[12]);
59
+
60
+    stringstream filenameprefix;
61
+    //void Data_File_Name (stringstream& name, char whichDSF, DP c_int, DP L, int N, int iKmin, int iKmax, DP kBT, DP L2)
62
+    Data_File_Name (filenameprefix, whichDSF, c_int, L, N, iKmin, iKmax, kBT, 0.0, "");
63
+    string prefix = filenameprefix.str();    
64
+
65
+    DP normalization = twoPI * L;
66
+    DP denom_sum_K = L;
67
+
68
+    Write_K_File (L, iKmin, iKmax);
69
+    Write_Omega_File (Nom, ommin, ommax);
70
+
71
+    // Read the weights from the ensembles file:
72
+    LiebLin_Diagonal_State_Ensemble ensemble;
73
+
74
+    stringstream ensfilestrstream;
75
+    //ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << "_ns_" << nstates_req << ".ens";
76
+    ensfilestrstream << "LiebLin_c_int_" << c_int << "_L_" << L << "_N_" << N << "_kBT_" << kBT << ".ens";
77
+    string ensfilestr = ensfilestrstream.str();
78
+    const char* ensfile_Cstr = ensfilestr.c_str();
79
+
80
+    ensemble.Load(c_int, L, N, ensfile_Cstr);
81
+
82
+    // Define the raw file names
83
+    Vect<string> rawfilename(ensemble.nstates);
84
+
85
+    for (int ns = 0; ns < ensemble.nstates; ++ns) {
86
+      // Define the raw input file name:
87
+      stringstream filenameprefix;
88
+      //Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, kBT, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);  
89
+      Data_File_Name (filenameprefix, whichDSF, iKmin, iKmax, 0.0, ensemble.state[ns], ensemble.state[ns], ensemble.state[ns].label);  
90
+      string prefix = filenameprefix.str();    
91
+      stringstream RAW_stringstream;    string RAW_string;
92
+      RAW_stringstream << prefix << ".raw";
93
+      //RAW_string = RAW_stringstream.str();    const char* RAW_Cstr = RAW_string.c_str();
94
+      rawfilename[ns] = RAW_stringstream.str();
95
+    }
96
+
97
+    Smoothen_RAW_into_SF (prefix, rawfilename, ensemble.weight, iKmin, iKmax, DiK, 
98
+			  ommin, ommax, Nom, width, normalization, denom_sum_K);
99
+
100
+  }
101
+
102
+  return(0);
103
+}

+ 82
- 0
src/EXECS/Smoothen_ODSLF_DSF.cc View File

@@ -0,0 +1,82 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  Smoothen_ODSLF_DSF.cc
10
+
11
+Purpose:  produces .dsf and .ssf files from a .raw file
12
+
13
+***********************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+using namespace JSC;
19
+
20
+
21
+int main(int argc, char* argv[]) 
22
+{
23
+  if (argc != 10 && argc != 11) { // Print out instructions
24
+    //if (strcmp(argv[1],"help") == 0) { // Output some instructions
25
+    cout << "Usage of Smoothen_ODSLF_DSF executable: " << endl << endl;
26
+    cout << "Provide arguments using one of the following options:" << endl << endl;
27
+    cout << "1) (for general momenta) whichDSF Delta N M iKmin iKmax ommin ommax Nom gwidth" << endl << endl;
28
+    cout << "2) (for fixed momentum) whichDSF Delta N M iKneeded ommin ommax Nom gwidth" << endl << endl;
29
+    //else JSCerror("Incomprehensible arguments in Smoothen_ODSLF_DSF executable.");
30
+  }
31
+
32
+  else if (argc == 11) { // !fixed_iK
33
+    char whichDSF = *argv[1];
34
+    DP Delta = atof(argv[2]);
35
+    int N = atoi(argv[3]);
36
+    int M = atoi(argv[4]);
37
+    int iKmin = atoi(argv[5]);
38
+    int iKmax = atoi(argv[6]);
39
+    DP ommin = atof(argv[7]);
40
+    DP ommax = atof(argv[8]);
41
+    int Nom = atoi(argv[9]);
42
+    DP gwidth = atof(argv[10]);
43
+
44
+    stringstream filenameprefix;
45
+    ODSLF_Data_File_Name (filenameprefix, whichDSF, Delta, N, M, iKmin, iKmax, 0.0, 0);
46
+    string prefix = filenameprefix.str();    
47
+
48
+    DP normalization = twoPI;
49
+
50
+    cout << "Smoothing:  sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
51
+
52
+    Write_K_File (N, iKmin, iKmax);
53
+    Write_Omega_File (Nom, ommin, ommax);
54
+
55
+  }
56
+
57
+  else if (argc == 10) { // fixed_iK
58
+    char whichDSF = *argv[1];
59
+    DP Delta = atof(argv[2]);
60
+    int N = atoi(argv[3]);
61
+    int M = atoi(argv[4]);
62
+    int iKneeded = atoi(argv[5]);
63
+    DP ommin = atof(argv[6]);
64
+    DP ommax = atof(argv[7]);
65
+    int Nom = atoi(argv[8]);
66
+    DP gwidth = atof(argv[9]);
67
+
68
+    bool fixed_iK = true;
69
+
70
+    stringstream filenameprefix;
71
+    Data_File_Name (filenameprefix, whichDSF, Delta, N, M, fixed_iK, iKneeded, 0.0, 0);
72
+    string prefix = filenameprefix.str();    
73
+
74
+    DP normalization = twoPI;
75
+    int iKmin = iKneeded;
76
+    int iKmax = iKneeded;
77
+
78
+    cout << "Smoothing:  sumcheck = " << Smoothen_RAW_into_SF (prefix, iKmin, iKmax, ommin, ommax, Nom, gwidth, normalization) << endl;
79
+  }
80
+
81
+  else JSCerror("Wrong number of arguments to Smoothen_Heis_DSF executable.");
82
+}

+ 112
- 0
src/EXECS/XXZ_gpd_StagSz_h0.cc View File

@@ -0,0 +1,112 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  ABACUS++G_2_testing.cc
10
+
11
+Purpose:  testing of ABACUS++2
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+using namespace JSC;
20
+
21
+
22
+int main( int argc, char* argv[]) 
23
+{
24
+  if (!(argc == 3 || argc == 5)) { // provide some info
25
+    cout << endl << "This code computes the (1/N) (-1)^j S^z_j on-site staggered magnetization for XXZ_gpd in zero field." << endl;
26
+    cout << "First option: provide two arguments: anisotropy Delta (> 1) and system size N (even)." << endl;
27
+    cout << "Second option: provide five arguments: system size N (even), Delta min, Delta max, NDelta." << endl;
28
+    cout << "The output is Delta, N, stag mag, energy gap." << endl;
29
+    JSCerror("");
30
+  }
31
+  else if (argc == 3) {
32
+    DP Delta = atof(argv[1]);
33
+    if (Delta <= 1.0) JSCerror("Provide Delta > 1.");
34
+    int N = atoi(argv[2]);
35
+    if (N % 2) JSCerror("Provide an even Delta.");
36
+    int M = N/2;
37
+
38
+    // Define the chain:  J, Delta, h, Nsites
39
+    Heis_Chain chain(1.0, Delta, 0.0, N);
40
+    
41
+    Heis_Base gbase(chain, M);
42
+
43
+    XXZ_gpd_Bethe_State gstate(chain, gbase);
44
+    gstate.Compute_All(true);
45
+
46
+    XXZ_gpd_Bethe_State estate(chain, gbase);
47
+    estate.Ix2[0][0] = M+1; // umklapp excitation
48
+    estate.Compute_All(true);
49
+
50
+    stringstream basestrstream;
51
+    basestrstream << M-2 << "x1";
52
+    string basestr = basestrstream.str();
53
+    Heis_Base basegap(chain, basestr);
54
+    XXZ_gpd_Bethe_State estategap(chain, basegap);
55
+    estategap.Compute_All(true);
56
+
57
+    if (!gstate.conv) JSCerror("Ground state did not converge.");
58
+    if (!estate.conv) JSCerror("Umklapp state did not converge.");
59
+    if (!estategap.conv) JSCerror("Gap state did not converge.");
60
+
61
+    cout << Delta << "\t" << N << "\t" << setprecision(12) << exp(real(ln_Sz_ME (gstate, estate)))/sqrt(N) << "\t" << estategap.E - gstate.E << endl;
62
+
63
+  }
64
+
65
+  else if (argc == 5) { // Do a scan in Delta
66
+
67
+    int N = atoi(argv[1]);
68
+    if (N % 2) JSCerror("Provide an even Delta.");
69
+    int M = N/2;
70
+
71
+    DP Deltamin = atof(argv[2]);
72
+    if (Deltamin <= 1.0) JSCerror("Provide Deltamin > 1.");
73
+
74
+    DP Deltamax = atof(argv[3]);
75
+    if (Deltamin <= 1.0) JSCerror("Provide Deltamax > Deltamin.");
76
+
77
+    int NDelta = atoi(argv[4]);
78
+
79
+    for (int iDelta = 0; iDelta <= NDelta; ++iDelta) {
80
+
81
+      DP Delta = (Deltamin * (NDelta -iDelta) + Deltamax * iDelta)/NDelta;
82
+
83
+      // Define the chain:  J, Delta, h, Nsites
84
+      Heis_Chain chain(1.0, Delta, 0.0, N);
85
+      
86
+      Heis_Base gbase(chain, M);
87
+      
88
+      XXZ_gpd_Bethe_State gstate(chain, gbase);
89
+      gstate.Compute_All(true);
90
+      
91
+      XXZ_gpd_Bethe_State estate(chain, gbase);
92
+      estate.Ix2[0][0] = M+1; // umklapp excitation
93
+      estate.Compute_All(true);
94
+      
95
+      stringstream basestrstream;
96
+      basestrstream << M-2 << "x1";
97
+      string basestr = basestrstream.str();
98
+      Heis_Base basegap(chain, basestr);
99
+      XXZ_gpd_Bethe_State estategap(chain, basegap);
100
+      estategap.Compute_All(true);
101
+      
102
+      if (!gstate.conv) JSCerror("Ground state did not converge.");
103
+      if (!estate.conv) JSCerror("Umklapp state did not converge.");
104
+      if (!estategap.conv) JSCerror("Gap state did not converge.");
105
+      
106
+      cout << Delta << "\t" << N << "\t" << setprecision(12) << exp(real(ln_Sz_ME (gstate, estate)))/sqrt(N) << "\t" << estategap.E - gstate.E << endl;
107
+      
108
+    }
109
+  }
110
+
111
+  return(0);
112
+}

+ 41
- 0
src/FITTING/covsrt.cc View File

@@ -0,0 +1,41 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's C++ library.
4
+
5
+Copyright (c) 2007.
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  mrqmin.cc
10
+
11
+Purpose:  Nonlinear fitting
12
+
13
+Last modified:  14/08/07
14
+
15
+***********************************************************/
16
+
17
+#include "JSC.h"
18
+
19
+using namespace std;
20
+
21
+namespace JSC {
22
+
23
+  void covsrt (SQMat_DP& covar, Vect<bool>& ia, const int mfit) 
24
+  {
25
+    int i, j, k;
26
+
27
+    int ma = ia.size();
28
+
29
+    for (i = mfit; i < ma; i++)
30
+      for (j = 0; j < i+1; j++) covar[i][j] = covar[j][i] = 0.0;
31
+    k = mfit - 1;
32
+    for (j = ma - 1; j >= 0; j--) {
33
+      if (ia[j]) {
34
+	for (i = 0; i < ma; i++) SWAP(covar[i][k], covar[i][j]);
35
+	for (i = 0; i < ma; i++) SWAP(covar[k][i], covar[j][i]);
36
+	k--;
37
+      }
38
+    }
39
+  }
40
+
41
+}

+ 73
- 0
src/FITTING/lin_reg.cc View File

@@ -0,0 +1,73 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's C++ library.
4
+
5
+Copyright (c) 2006.
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  lin_reg.cc
10
+
11
+Purpose:  Linear regression
12
+
13
+Last modified:  11/05/07
14
+
15
+***********************************************************/
16
+
17
+#include "JSC.h"
18
+
19
+using namespace std;
20
+
21
+namespace JSC {
22
+
23
+  void lin_reg (Vect_DP x, Vect_DP y, Vect_DP sigma, DP& a, DP& b, DP& chisq)
24
+  {
25
+    // Performs simple linear regression on data
26
+
27
+    int Npts = x.size();
28
+
29
+    DP S = 0.0;
30
+    DP Sx = 0.0;
31
+    DP Sy = 0.0;
32
+    DP Stt = 0.0;
33
+    Vect_DP t(0.0, Npts);
34
+
35
+    for (int i = 0; i < Npts; ++i) {
36
+      S += 1.0/(sigma[i] * sigma[i]);
37
+      Sx += x[i]/(sigma[i] * sigma[i]);
38
+      Sy += y[i]/(sigma[i] * sigma[i]);
39
+    }
40
+
41
+    for (int i = 0; i < Npts; ++i) {
42
+      t[i] = (x[i] - Sx/S)/sigma[i];
43
+      Stt += t[i] * t[i];
44
+    }
45
+
46
+    a = 0.0;
47
+    b = 0.0;
48
+    for (int i = 0; i < Npts; ++i) {
49
+      b += t[i] * y[i]/sigma[i];
50
+    }
51
+    b /= Stt;
52
+    a = (Sy - Sx * b)/S;
53
+
54
+    chisq = 0.0;
55
+    for (int i = 0; i < Npts; ++i) {
56
+      chisq += (y[i] - a - b * x[i]) * (y[i] - a - b * x[i]) / (sigma[i] * sigma[i]);
57
+    }
58
+
59
+    return;
60
+  }
61
+
62
+  void lin_reg (Vect_DP x, Vect_DP y, DP& a, DP& b, DP& chisq)
63
+  {
64
+    // Assumes all sigma == 1
65
+
66
+    Vect_DP sigma(1.0, x.size());
67
+
68
+    lin_reg (x, y, sigma, a, b, chisq);
69
+
70
+    return;
71
+  }
72
+
73
+}

+ 127
- 0
src/FITTING/mrq.cc View File

@@ -0,0 +1,127 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's C++ library.
4
+
5
+Copyright (c) 2007.
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  mrqmin.cc
10
+
11
+Purpose:  Nonlinear fitting
12
+
13
+Last modified:  14/08/07
14
+
15
+***********************************************************/
16
+
17
+#include "JSC.h"
18
+
19
+using namespace std;
20
+
21
+namespace JSC {
22
+
23
+  void mrqmin (Vect_DP& x, Vect_DP& y, Vect_DP& sig, Vect_DP& a, 
24
+	       Vect<bool>& ia, SQMat_DP& covar, SQMat_DP& alpha, DP& chisq,
25
+	       void funcs(const DP, Vect_DP&, DP&, Vect_DP&), DP& alambda)
26
+  {
27
+    // Levenberg-Marquardt method.  See NRC++ p.691.
28
+
29
+    static int mfit;
30
+    static DP ochisq;
31
+    int j, k, l;
32
+
33
+    int ma = a.size();
34
+    static SQMat_DP oneda (ma);
35
+    static Vect_DP atry(ma);
36
+    static Vect_DP beta(ma);
37
+    static Vect_DP da(ma);
38
+
39
+    if (alambda < 0.0) {
40
+      mfit = 0;
41
+      for (j = 0; j < ma; j++)
42
+	if (ia[j]) mfit++;
43
+      alambda = 0.001;
44
+      mrqcof (x, y, sig, a, ia, alpha, beta, chisq, funcs);
45
+      ochisq = chisq;
46
+      for (j = 0; j < ma; j++) atry[j] = a[j];
47
+    }
48
+
49
+    SQMat_DP temp (mfit);
50
+
51
+    for (j = 0; j < mfit; j++) {
52
+      for (k = 0; k < mfit; k++) covar[j][k] = alpha[j][k];
53
+      covar[j][j] = alpha[j][j] * (1.0 + alambda);
54
+      for (k = 0; k < mfit; k++) temp[j][k] = covar[j][k];
55
+      oneda[j][0] = beta[j];
56
+    }
57
+
58
+    gaussj (temp, oneda);
59
+    for (j = 0; j < mfit; j++) {
60
+      for (k = 0; k < mfit; k++) covar[j][k] = temp[j][k];
61
+      da[j] = oneda[j][0];
62
+    }
63
+
64
+    if (alambda == 0.0) {
65
+      covsrt (covar, ia, mfit);
66
+      covsrt (alpha, ia, mfit);
67
+      return;
68
+    }
69
+
70
+    for (j = 0, l = 0; l < ma; l++)
71
+      if (ia[l]) atry[l] = a[l] + da[j++];
72
+
73
+    mrqcof (x, y, sig, atry, ia, covar, da, chisq, funcs);
74
+
75
+    if (chisq < ochisq) {
76
+      alambda *= 0.1;
77
+      ochisq = chisq;
78
+      for (j = 0; j < mfit; j++) {
79
+	for (k = 0; k < mfit; k++) alpha[j][k] = covar[j][k];
80
+	beta[j] = da[j];
81
+      }
82
+      for (l = 0; l < ma; l++) a[l] = atry[l];
83
+    } else {
84
+      alambda *= 10.0;
85
+      chisq = ochisq;
86
+    }
87
+  }
88
+
89
+  void mrqcof (Vect_DP& x, Vect_DP& y, Vect_DP& sig, Vect_DP& a,
90
+	       Vect<bool>& ia, SQMat_DP& alpha, Vect_DP& beta, DP& chisq,
91
+	       void funcs (const DP, Vect_DP&, DP&, Vect_DP&))
92
+  {
93
+    int i, j, k, l, m, mfit = 0;
94
+    DP ymod, wt, sig2i, dy;
95
+
96
+    int ndata = x.size();
97
+    int ma = a.size();
98
+
99
+    Vect_DP dyda (ma);
100
+
101
+    for (j = 0; j < ma; j++)
102
+      if (ia[j]) mfit++;
103
+    for (j = 0; j < mfit; j++) {
104
+      for (k = 0; k <= j; k++) alpha[j][k] = 0.0;
105
+      beta[j] = 0.0;
106
+    }
107
+
108
+    chisq = 0.0;
109
+    for (i = 0; i < ndata; i++) {
110
+      funcs (x[i], a, ymod, dyda);
111
+      sig2i = 1.0/(sig[i] * sig[i]);
112
+      dy = y[i] - ymod;
113
+      for (j = 0, l = 0; l < ma; l++) {
114
+	if (ia[l]) {
115
+	  wt = dyda[l] * sig2i;
116
+	  for (k = 0, m = 0; m < l+1; m++)
117
+	    if (ia[m]) alpha[j][k++] += wt * dyda[m];
118
+	  beta[j++] += dy * wt;
119
+	}
120
+      }
121
+      chisq += dy * dy * sig2i;
122
+    }
123
+    for (j = 1; j < mfit; j++)
124
+      for (k = 0; k < j; k++) alpha[k][j] = alpha[j][k];
125
+  }
126
+
127
+}

+ 35
- 0
src/FITTING/polint.cc View File

@@ -0,0 +1,35 @@
1
+#include "JSC.h"
2
+using namespace std;
3
+
4
+void JSC::polint(Vect_DP& xa, Vect_DP& ya, const DP x, DP& y, DP& dy)
5
+{
6
+  // Polynomial interpolation/extrapolation, NR page 113.
7
+
8
+  int i, m, ns=0;
9
+  DP den, dif, dift, ho, hp, w;
10
+
11
+  int n = xa.size();
12
+  Vect_DP c(n), d(n);
13
+  dif = fabs(x-xa[0]);
14
+  for (i = 0; i < n; i++) {
15
+    if ((dift = fabs(x-xa[i])) < dif) {
16
+      ns = i;
17
+      dif = dift;
18
+    }
19
+    c[i] = ya[i];
20
+    d[i] = ya[i];
21
+  }
22
+  y = ya[ns--];
23
+  for (m = 1; m < n; m++) {
24
+    for (i = 0; i < n-m; i++) {
25
+      ho = xa[i] - x;
26
+      hp = xa[i+m] - x;
27
+      w = c[i+1] - d[i];
28
+      if ((den = ho-hp) == 0.0) JSCerror("Error in routine polint.");
29
+      den = w/den;
30
+      d[i] = hp * den;
31
+      c[i] = ho * den;
32
+    }
33
+    y += (dy = (2 * (ns + 1) < (n-m) ? c[ns + 1] : d[ns--]));
34
+  }
35
+}

+ 36
- 0
src/FITTING/polint_cx.cc View File

@@ -0,0 +1,36 @@
1
+#include "JSC.h"
2
+using namespace std;
3
+
4
+void JSC::polint(Vect_CX& xa, Vect_CX& ya, const complex<DP> x, complex<DP>& y, complex<DP>& dy)
5
+{
6
+  // Polynomial interpolation/extrapolation, NR page 113.
7
+
8
+  int i, m, ns=0;
9
+  DP dif, dift;
10
+  complex<DP> den, ho, hp, w;
11
+
12
+  int n = xa.size();
13
+  Vect_CX c(n), d(n);
14
+  dif = abs(x-xa[0]);
15
+  for (i = 0; i < n; i++) {
16
+    if ((dift = abs(x-xa[i])) < dif) {
17
+      ns = i;
18
+      dif = dift;
19
+    }
20
+    c[i] = ya[i];
21
+    d[i] = ya[i];
22
+  }
23
+  y = ya[ns--];
24
+  for (m = 1; m < n; m++) {
25
+    for (i = 0; i < n-m; i++) {
26
+      ho = xa[i] - x;
27
+      hp = xa[i+m] - x;
28
+      w = c[i+1] - d[i];
29
+      if ((den = ho-hp) == 0.0) JSCerror("Error in routine polint_cx.");
30
+      den = w/den;
31
+      d[i] = hp * den;
32
+      c[i] = ho * den;
33
+    }
34
+    y += (dy = (2 * (ns + 1) < (n-m) ? c[ns + 1] : d[ns--]));
35
+  }
36
+}

+ 1717
- 0
src/HEIS/Heis.cc
File diff suppressed because it is too large
View File


+ 142
- 0
src/HEIS/Heis_Chem_Pot.cc View File

@@ -0,0 +1,142 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c) 
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  src/HEIS/Heis_Chem_Pot.cc
10
+
11
+Purpose:  calculates the chemical potential.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+namespace JSC { 
19
+
20
+  DP Ezero (DP Delta, int N, int M)
21
+  {
22
+    // Returns the energy of the ground state with M down spins
23
+
24
+    if (M < 0 || M > N/2) JSCerror("M out of bounds in Ezero.");
25
+   
26
+    DP E = -1.0; // sentinel value
27
+
28
+    if (M == 0) E = N * Delta/4.0;
29
+
30
+    else {
31
+
32
+      Heis_Chain BD1(1.0, Delta, 0.0, N);
33
+      
34
+      Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
35
+      
36
+      Nrapidities_groundstate[0] = M;
37
+      
38
+      Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
39
+      
40
+      if ((Delta > 0.0) && (Delta < 1.0)) {
41
+	XXZ_Bethe_State groundstate(BD1, baseconfig_groundstate);
42
+	groundstate.Compute_All(true);
43
+	E = groundstate.E;
44
+      }
45
+      
46
+      else if (Delta == 1.0) {
47
+	XXX_Bethe_State groundstate(BD1, baseconfig_groundstate);
48
+	groundstate.Compute_All(true);
49
+	E = groundstate.E;
50
+      }
51
+      
52
+      else if (Delta > 1.0) {
53
+	XXZ_gpd_Bethe_State groundstate(BD1, baseconfig_groundstate);
54
+	groundstate.Compute_All(true);
55
+	E = groundstate.E;
56
+      }
57
+      
58
+      else JSCerror("Anisotropy out of bounds in Ezero.");
59
+    }
60
+
61
+    return(E);
62
+  }
63
+
64
+  DP H_vs_M (DP Delta, int N, int M)
65
+  {
66
+    // Assumes dE/dM = 0 = dE_0/dM + h, with dE_0/dM = E_0(M) - E_0 (M - 1)
67
+
68
+    DP H = 0.0;
69
+
70
+    if (2*M == N) H = 0.0; 
71
+
72
+    else if (Delta <= 1.0) H = Ezero (Delta, N, M - 1) - Ezero (Delta, N, M);
73
+
74
+    return(H);
75
+  }
76
+
77
+  DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref)
78
+  {
79
+    if (M < 0 || M > N/2 - 1) {
80
+      cout << "M = " << M << endl;
81
+      JSCerror("M out of bounds in HZmin.");    
82
+    }
83
+
84
+    if (Ezero_ref[M] == -1.0) Ezero_ref[M] = Ezero(Delta, N, M);
85
+    if (Ezero_ref[M + 1] == -1.0) Ezero_ref[M + 1] = Ezero(Delta, N, M + 1);
86
+
87
+    return(Ezero_ref[M] - Ezero_ref[M + 1]);
88
+  }
89
+
90
+  int M_vs_H (DP Delta, int N, DP HZ)
91
+  {
92
+    // Returns the value of M for given field HZ
93
+
94
+    if (HZ < 0.0) JSCerror("Please use a positive field in M_vs_H.");
95
+
96
+    else if (HZ == 0.0) return(N/2);
97
+
98
+    // Here, -1.0 is a sentinel value.
99
+    Vect_DP Ezero(-1.0, N/2 + 1);  // contains the GSE[M].
100
+
101
+    // We look for M s.t. HZmin[M] < HZ <= HZmin[M + 1]
102
+
103
+    int M_actual = N/4; // start somewhere in middle
104
+    int M_step = N/8 - 1; // step
105
+    DP HZmin_actual = 0.0;
106
+    DP HZmax_actual = 0.0;
107
+    bool M_found = false;
108
+
109
+    if (HZ >= 1.0 + Delta) M_actual = 0;  // saturation
110
+
111
+    else {
112
+      
113
+      HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
114
+      HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
115
+
116
+      while (!M_found) {
117
+
118
+	if (HZmin_actual > HZ) M_actual += M_step;
119
+	else if (HZmax_actual <= HZ) M_actual -= M_step;
120
+	
121
+	M_step = (M_step + 1)/2;
122
+
123
+	HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
124
+	HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
125
+
126
+	M_found = (HZmin_actual < HZ && HZ <= HZmax_actual);	
127
+
128
+	//cout << "M_actual = " << M_actual << "\tM_step = " << M_step 
129
+	//   << "\tHZmin_actual = " << HZmin_actual << "\tHZmax_actual = " << HZmax_actual << "\tHZ = " << HZ << "\t" << M_found << endl;
130
+      }
131
+    }
132
+    //cout << "M found = " << M_actual << "\tHZmax = " << Ezero[M_actual] - Ezero[M_actual + 1] << "\tHZmin = " << Ezero[M_actual - 1] - Ezero[M_actual] << endl;
133
+
134
+    return(M_actual);
135
+  }
136
+
137
+  DP Chemical_Potential (const Heis_Bethe_State& AveragingState)
138
+  {
139
+    return(-H_vs_M (AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown));  // - sign since E_{M+1} - E_M = -H
140
+  }
141
+
142
+}

+ 376
- 0
src/HEIS/Heis_Matrix_Element_Contrib.cc View File

@@ -0,0 +1,376 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  src/HEIS/Heis_Matrix_Element_Contrib.cc
10
+
11
+Purpose:  handles the generic call for a matrix element.
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+using namespace JSC;
20
+
21
+namespace JSC {
22
+
23
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXZ_Bethe_State& LeftState, 
24
+				     //XXZ_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
25
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState, 
26
+  //				     XXZ_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
27
+  DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_Bethe_State& LeftState, 
28
+				     XXZ_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
29
+  {
30
+    // This function prints the matrix information to the fstream,
31
+    // and returns a weighed `data_value' to be multiplied by sumrule_factor,
32
+    // to determine if scanning along this thread should be continued.
33
+
34
+    // Identify which matrix element is needed from the number of particles in Left and Right states:
35
+
36
+    bool fixed_iK = (iKmin == iKmax);
37
+
38
+    DP ME = 0.0;
39
+    if (!(LeftState.conv && RightState.conv)) ME = 0.0;
40
+
41
+    else if (whichDSF == 'Z')
42
+      ME = LeftState.E - RightState.E;
43
+    else if (whichDSF == 'm')
44
+      ME = exp(real(ln_Smin_ME (RightState, LeftState)));
45
+    else if (whichDSF == 'z') {
46
+      if (LeftState.label == RightState.label)
47
+	//MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
48
+	ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
49
+      else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
50
+    }
51
+    else if (whichDSF == 'p')
52
+      ME = exp(real(ln_Smin_ME (LeftState, RightState)));
53
+    else JSCerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
54
+
55
+    if (is_nan(ME)) ME = 0.0;
56
+
57
+    //if (LeftState.dev > 1.0e-16 || RightState.dev > 1.0e-16) ME = 0.0; // kill deviated contributions
58
+
59
+    // Do the momentum business:
60
+    int iKout = LeftState.iK - RightState.iK;
61
+    while(iKout < 0) iKout += RightState.chain.Nsites;
62
+    while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
63
+
64
+    // Print information to fstream:
65
+    if (iKout >= iKmin && iKout <= iKmax) {
66
+      if (whichDSF == 'Z') {
67
+	DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" 
68
+		    << iKout << "\t"
69
+	  //<< LeftState.conv << "\t" 
70
+		    << setprecision(3) << LeftState.dev << "\t"
71
+		    << LeftState.label;
72
+      }
73
+      else {
74
+	DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" 
75
+		    << iKout << "\t"
76
+		    << ME << "\t"
77
+	  //<< LeftState.conv << "\t" 
78
+		    << setprecision(3) << LeftState.dev << "\t"
79
+		    << LeftState.label;
80
+      }
81
+    } // if iKmin <= iKout <= iKmax
82
+
83
+    // Calculate and return the data_value:
84
+    DP data_value = ME * ME;
85
+    //DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
86
+
87
+    if (whichDSF == 'Z') // use 1/(1 + omega)
88
+      data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
89
+    else if (fixed_iK) // data value is MEsq * omega:
90
+      data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
91
+
92
+    return(data_value);
93
+  }
94
+
95
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXX_Bethe_State& LeftState, 
96
+                          //XXX_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
97
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState, 
98
+  //XXX_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
99
+  DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXX_Bethe_State& LeftState, 
100
+				     XXX_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
101
+  {
102
+    // This function prints the matrix element information to the fstream,
103
+    // and returns a weighed `data_value' to be multiplied by sumrule_factor,
104
+    // to determine if scanning along this thread should be continued.
105
+
106
+    // Identify which matrix element is needed from the number of particles in Left and Right states:
107
+
108
+    bool fixed_iK = (iKmin == iKmax);
109
+
110
+    DP ME = 0.0;
111
+    complex<DP> ME_CX = 0.0;
112
+
113
+    int nrinfrap = 0; // for energy shift from chemical potential
114
+
115
+    if (!(LeftState.conv && RightState.conv)) { ME = 0.0; ME_CX = 0.0;}
116
+
117
+    else if (whichDSF == 'Z')
118
+      ME = LeftState.E - RightState.E;
119
+    else if (whichDSF == 'm')
120
+      ME = exp(real(ln_Smin_ME (RightState, LeftState)));
121
+    else if (whichDSF == 'z') {
122
+      // Recognize the presence of an infinite rapidity:
123
+      if (LeftState.base.Mdown == RightState.base.Mdown - 1) { // infinite rapidity present, use rescaled S^- matrix element instead of S^z one:
124
+	nrinfrap = 1;
125
+	// Correction factor for MEsq: Smffsq to Szffsq = 1/(N - 2M + 2)
126
+	ME = sqrt(1.0/(RightState.chain.Nsites - 2*RightState.base.Mdown + 2)) * exp(real(ln_Smin_ME (RightState, LeftState)));
127
+      }
128
+      else { // no infinite rapidity, use S^z matrix element:
129
+	if (LeftState.label == RightState.label)
130
+	  //MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
131
+	  ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
132
+	else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
133
+      }
134
+    }
135
+    else if (whichDSF == 'p') {
136
+      // Recognize the presence of two infinite rapidities:
137
+      if (LeftState.base.Mdown == RightState.base.Mdown - 1) { // two infinite rapidities, use rescaled S^- matrix element instead of S^+
138
+	nrinfrap = 2;
139
+	// Correction factor for MEsq: Smffsq to Spffsq = 2/((N - 2M + 2) (N - 2M + 1))
140
+	ME = sqrt(2.0/((RightState.chain.Nsites - 2*RightState.base.Mdown + 2.0) * (RightState.chain.Nsites - 2*RightState.base.Mdown + 1.0))) 
141
+	  * exp(real(ln_Smin_ME (RightState, LeftState)));
142
+      }
143
+      else if (LeftState.base.Mdown == RightState.base.Mdown) { // one infinite rapidity, use rescaled S^z matrix element instead of S^+
144
+	nrinfrap = 1;
145
+	// Correction factor for MEsq: Szffsq to Spffsq = 4/(N - 2M)
146
+	ME = sqrt(4.0/(RightState.chain.Nsites - 2* RightState.base.Mdown)) * exp(real(ln_Sz_ME (RightState, LeftState)));
147
+      }
148
+      else ME = exp(real(ln_Smin_ME (LeftState, RightState)));
149
+    }
150
+    else if (whichDSF == 'a') // S^z_j S^z_{j+1} operator
151
+      ME = exp(real(ln_Szz_ME (LeftState, RightState)));
152
+    else if (whichDSF == 'b') // S^z_j S^-_{j+1} + h.c. operator
153
+      ME = exp(real(ln_Szm_p_Smz_ME (RightState, LeftState)));
154
+    else if (whichDSF == 'c') // S^-_j S^-{j+1} operator
155
+      ME = exp(real(ln_Smm_ME (RightState, LeftState)));
156
+    else if (whichDSF == 'q') // Geometric quench
157
+      //ME_CX = ln_Overlap (LeftState, RightState);
158
+      ME_CX = ln_Overlap (RightState, LeftState);
159
+    else JSCerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
160
+
161
+    if (is_nan(ME)) ME = 0.0;
162
+    if (is_nan(norm(ME_CX))) ME_CX = -100.0;
163
+
164
+    //if (LeftState.dev > 1.0e-16 || RightState.dev > 1.0e-16) {
165
+    //ME = 0.0; ME_CX = (0.0,0.0); // kill deviated contributions
166
+    //}
167
+
168
+    // Do the momentum business:
169
+    int iKout = LeftState.iK - RightState.iK;
170
+    while(iKout < 0) iKout += RightState.chain.Nsites;
171
+    while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
172
+
173
+    // Print information to fstream:
174
+    if (iKout >= iKmin && iKout <= iKmax) {
175
+      if (whichDSF == 'Z') {
176
+	DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t" 
177
+		    << iKout << "\t"
178
+	  //<< LeftState.conv << "\t" 
179
+		    << setprecision(3) << LeftState.dev << "\t"
180
+		    << LeftState.label;
181
+      }
182
+      else if (whichDSF == 'q') {
183
+	DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t" 
184
+		    << iKout << "\t"
185
+		    << real(ME_CX) << "\t" << imag(ME_CX) - twoPI * int(imag(ME_CX)/twoPI + 1.0e-10) << "\t"
186
+	  //<< LeftState.conv << "\t" 
187
+		    << setprecision(3) << LeftState.dev << "\t"
188
+		    << LeftState.label;
189
+      }
190
+
191
+      else {
192
+	DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown + nrinfrap - RightState.base.Mdown) * Chem_Pot << "\t" 
193
+		    << iKout << "\t"
194
+		    << ME << "\t"
195
+	  //<< LeftState.conv << "\t" 
196
+		    << setprecision(3) << LeftState.dev << "\t"
197
+		    << LeftState.label;
198
+      }
199
+    } // if iKmin <= iKout <= iKmax
200
+
201
+    // Calculate and return the data_value:
202
+    DP data_value = ME * ME;
203
+    //DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
204
+    if (whichDSF == 'Z') // use 1/(1 + omega)
205
+      data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
206
+    else if (whichDSF == 'q') 
207
+      data_value = exp(2.0 * real(ME_CX));
208
+    else if (fixed_iK) // data value is MEsq * omega:
209
+      data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
210
+
211
+    return(data_value);
212
+  }
213
+
214
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, bool fixed_iK, XXZ_gpd_Bethe_State& LeftState, 
215
+  //XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
216
+  //DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState, 
217
+  //				     XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, fstream& DAT_outfile)
218
+  DP Compute_Matrix_Element_Contrib (char whichDSF, int iKmin, int iKmax, XXZ_gpd_Bethe_State& LeftState, 
219
+				     XXZ_gpd_Bethe_State& RightState, DP Chem_Pot, stringstream& DAT_outfile)
220
+  {
221
+    // This function prints the matrix element information to the fstream,
222
+    // and returns a weighed `data_value' to be multiplied by sumrule_factor,
223
+    // to determine if scanning along this thread should be continued.
224
+
225
+    /*
226
+    cout << "\t" << LeftState.label << endl << "\t" << LeftState.Ix2 << endl;
227
+    cout << "\t0: ";
228
+    for (int i = 0; i < LeftState.base.Nrap[0]; ++i) cout << LeftState.lambda[0][i]*2.0/PI << "\t";
229
+    cout << endl;
230
+    cout << "\t1: ";
231
+    for (int i = 0; i < LeftState.base.Nrap[1]; ++i) cout << LeftState.lambda[1][i]*2.0/PI << "\t";
232
+    cout << endl;
233
+    */
234
+
235
+    bool fixed_iK = (iKmin == iKmax);
236
+    
237
+
238
+    // If any of the rapidities outside of fundamental interval -pi/2 < lambda <= pi/2, set matrix element to zero.
239
+    bool rap_in_fundamental = true;
240
+    int sum1 = 0;
241
+    for (int j = 0; j < LeftState.chain.Nstrings; ++j) {
242
+      //for (int alpha = 0; alpha < LeftState.base.Nrap[j]; ++alpha) {
243
+	//if (LeftState.lambda[j][alpha] <= -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
244
+	//if (LeftState.lambda[j][alpha] <= -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
245
+      //rap_in_fundamental = false;
246
+      //}
247
+
248
+      /*
249
+      // TEST 2014 06 26: comment this out, replace by -\pi/2 \leq \lambda \leq \pi/2, see below
250
+      if (LeftState.base.Nrap[j] > 0 && LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
251
+      rap_in_fundamental = false;
252
+
253
+      sum1 = 0;
254
+      for (int k = 0; k < LeftState.chain.Nstrings; ++k)
255
+	sum1 += LeftState.base.Nrap[k] * (2 * JSC::min(LeftState.chain.Str_L[j], LeftState.chain.Str_L[k]) - ((j == k) ? 1 : 0));
256
+      // This almost does it:  only missing are the states with one on -PI/2 and one on PI/2
257
+      if (LeftState.base.Nrap[j] >= 1 
258
+	  && (LeftState.Ix2[j][0] <= -(LeftState.chain.Nsites - sum1) 
259
+	      || (LeftState.Ix2[j][LeftState.base.Nrap[j] - 1] - LeftState.Ix2[j][0]) 
260
+	      > 2*(LeftState.chain.Nsites - sum1)))
261
+	rap_in_fundamental = false;
262
+      */
263
+
264
+      // attempt 2014 06 26
265
+      //for (int alpha = 0; alpha < LeftState.base.Nrap[j]; ++alpha) {
266
+      //if (LeftState.lambda[j][alpha] < -0.5*PI || LeftState.lambda[j][alpha] > 0.5*PI)
267
+      //  rap_in_fundamental = false;
268
+      //}
269
+      /*
270
+      if (LeftState.base.Nrap[j] > 0 && 
271
+	  ((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
272
+	   || LeftState.lambda[j][0] < -0.5*PI + 1.0e-10
273
+	   || LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > 0.5*PI
274
+	   //|| LeftState.lambda[j][0] > 0.5*PI
275
+	   //((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI - 1.0e-10)
276
+	   //|| LeftState.lambda[j][0] < -0.5*PI + 1.0e-10
277
+	   //|| LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > 0.5*PI + 1.0e-10
278
+	   )) // include safety in limits
279
+	rap_in_fundamental = false;
280
+      */
281
+      /*
282
+      if (LeftState.base.Nrap[j] > 0 && 
283
+	  ((LeftState.lambda[j][LeftState.base.Nrap[j] - 1] - LeftState.lambda[j][0] >= PI)
284
+	   //|| (LeftState.base.Nrap[j] == 1 && fabs(LeftState.lambda[j][0]) > 0.5*PI)
285
+	   ))
286
+	rap_in_fundamental = false;
287
+      */
288
+
289
+      // Logic: allow rapidities -PI/2 <= lambda <= PI/2 (including boundaries)
290
+      if (LeftState.base.Nrap[j] > 0 && 
291
+	  (LeftState.lambda[j][0] < -PI/2 || LeftState.lambda[j][LeftState.base.Nrap[j] - 1] > PI/2))
292
+	rap_in_fundamental = false;
293
+      if (RightState.base.Nrap[j] > 0 && 
294
+	  (RightState.lambda[j][0] < -PI/2 || RightState.lambda[j][RightState.base.Nrap[j] - 1] > PI/2))
295
+	rap_in_fundamental = false;
296
+
297
+      // rapidities should also be ordered as the quantum numbers:
298
+      for (int alpha = 1; alpha < LeftState.base.Nrap[j]; ++alpha)
299
+	if (LeftState.lambda[j][alpha - 1] >= LeftState.lambda[j][alpha])
300
+	  rap_in_fundamental = false;
301
+      for (int alpha = 1; alpha < RightState.base.Nrap[j]; ++alpha)
302
+	if (RightState.lambda[j][alpha - 1] >= RightState.lambda[j][alpha])
303
+	  rap_in_fundamental = false;
304
+
305
+    } // for int j
306
+
307
+
308
+    // Identify which matrix element is needed from the number of particles in Left and Right states:
309
+    DP ME = 0.0;
310
+    //if (!(LeftState.conv && RightState.conv)) ME = 0.0;
311
+    if (!(LeftState.conv && RightState.conv && rap_in_fundamental)) ME = 0.0;
312
+
313
+    else if (whichDSF == 'Z')
314
+      ME = LeftState.E - RightState.E;
315
+    else if (whichDSF == 'm')
316
+      ME = exp(real(ln_Smin_ME (RightState, LeftState)));
317
+    else if (whichDSF == 'z') {
318
+      if (LeftState.label == RightState.label)
319
+	//MEsq = RightState.chain.Nsites * 0.25 * pow((1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites), 2.0);
320
+	ME = sqrt(RightState.chain.Nsites * 0.25) * (1.0 - 2.0*RightState.base.Mdown/RightState.chain.Nsites);
321
+      else ME = exp(real(ln_Sz_ME (RightState, LeftState)));
322
+    }
323
+    else if (whichDSF == 'p')
324
+      ME = exp(real(ln_Smin_ME (LeftState, RightState)));
325
+    else JSCerror("Wrong whichDSF in Compute_Matrix_Element_Contrib.");
326
+
327
+    if (is_nan(ME)) ME = 0.0;
328
+
329
+    //if (LeftState.dev > 1.0e+2 || RightState.dev > 1.0e+2) ME = 0.0; // kill deviated contributions
330
+    if (fabs(ME) > 1.0) ME = 0.0;
331
+
332
+    // Do the momentum business:
333
+    int iKout = LeftState.iK - RightState.iK;
334
+    while(iKout < 0) iKout += RightState.chain.Nsites;
335
+    while(iKout >= RightState.chain.Nsites) iKout -= RightState.chain.Nsites;
336
+
337
+    // Print information to fstream:
338
+    if (iKout >= iKmin && iKout <= iKmax) {
339
+      if (whichDSF == 'Z') {
340
+	DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" 
341
+		    << iKout << "\t"
342
+	  //<< LeftState.conv << "\t" 
343
+		    << setprecision(3) << LeftState.dev << "\t"
344
+		    << LeftState.label;
345
+      }
346
+      else {
347
+	DAT_outfile << endl << setprecision(16) << LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot << "\t" 
348
+		    << iKout << "\t"
349
+		    << ME << "\t"
350
+	  //<< LeftState.conv << "\t" 
351
+		    << setprecision(3) << LeftState.dev << "\t"
352
+		    << LeftState.label;
353
+
354
+	/*
355
+	  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];
356
+	  if (LeftState.base.Nrap[1] > 0) cout << "\t" << LeftState.lambda[1][0]/PI << "\t" << LeftState.Ix2[1][0];
357
+	  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" << "*****";
358
+	  cout << endl;
359
+	*/
360
+
361
+      }
362
+    } // if iKmin <= iKout <= iKmax
363
+
364
+    // Calculate and return the data_value:
365
+    DP data_value = ME * ME;
366
+    //DP data_value = (iKout == 0 ? 1.0 : 2.0) * MEsq;
367
+    if (whichDSF == 'Z') // use 1/(1 + omega)
368
+      data_value = 1.0/(1.0 + LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
369
+    else if (fixed_iK) // data value is MEsq * omega:
370
+      data_value = ME * ME * (LeftState.E - RightState.E - (LeftState.base.Mdown - RightState.base.Mdown) * Chem_Pot);
371
+
372
+    return(data_value);
373
+  }
374
+
375
+
376
+} // namespace JSC

+ 255
- 0
src/HEIS/Heis_Sumrules.cc View File

@@ -0,0 +1,255 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  src/HEIS/Heis_Sumrules.cc
10
+
11
+Purpose:  defines sumrule factors for Heisenberg
12
+
13
+
14
+***********************************************************/
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+
20
+namespace JSC {
21
+
22
+  DP X_avg (char xyorz, DP Delta, int N, int M)
23
+  {
24
+    // Calculates \sum_j < S_j^a S_{j+1}^a >, a = x, y or z.
25
+
26
+    DP eps_Delta = 0.00000001;
27
+
28
+    if (Delta < 1.0 && 1.0 - Delta < 1.0e-6) eps_Delta *= -1.0;
29
+
30
+    // Define the chain:  J, Delta, h, Nsites
31
+    Heis_Chain chain(1.0, Delta, 0.0, N);
32
+    
33
+    // Define the base:  chain, Mdown
34
+    Heis_Base gbase(chain, M);
35
+
36
+    // Define the chain:  J, Delta, h, Nsites
37
+    Heis_Chain chain2(1.0, Delta + eps_Delta, 0.0, N);
38
+    
39
+    // Define the base:  chain, Mdown
40
+    Heis_Base gbase2(chain2, M);
41
+    
42
+    DP E0_Delta = 0.0;
43
+    DP E0_Delta_eps = 0.0; 
44
+
45
+    if (Delta > 0.0 && Delta < 1.0) {
46
+
47
+      // Define the ground state
48
+      XXZ_Bethe_State gstate(chain, gbase);
49
+    
50
+      // Compute everything about the ground state
51
+      gstate.Compute_All(true);
52
+
53
+      E0_Delta = gstate.E;
54
+
55
+      // Define the ground state
56
+      XXZ_Bethe_State gstate2(chain2, gbase2);
57
+    
58
+      // Compute everything about the ground state
59
+      gstate2.Compute_All(true);
60
+
61
+      E0_Delta_eps = gstate2.E;
62
+    }
63
+
64
+    else if (Delta == 1.0) {
65
+      // Define the ground state
66
+      XXX_Bethe_State gstate(chain, gbase);
67
+    
68
+      // Compute everything about the ground state
69
+      gstate.Compute_All(true);
70
+
71
+      E0_Delta = gstate.E;
72
+
73
+      // Define the ground state
74
+      XXZ_gpd_Bethe_State gstate2(chain2, gbase2);  // need XXZ_gpd here
75
+    
76
+      // Compute everything about the ground state
77
+      gstate2.Compute_All(true);
78
+
79
+      E0_Delta_eps = gstate2.E;
80
+    }
81
+
82
+    else if (Delta > 1.0) {
83
+      // Define the ground state
84
+      XXZ_gpd_Bethe_State gstate(chain, gbase);
85
+    
86
+      // Compute everything about the ground state
87
+      gstate.Compute_All(true);
88
+
89
+      E0_Delta = gstate.E;
90
+
91
+      // Define the ground state
92
+      XXZ_gpd_Bethe_State gstate2(chain2, gbase2);
93
+    
94
+      // Compute everything about the ground state
95
+      gstate2.Compute_All(true);
96
+
97
+      E0_Delta_eps = gstate2.E;
98
+    }
99
+
100
+    else JSCerror("Wrong anisotropy in S1_sumrule_factor.");
101
+
102
+    DP answer = 0.0;
103
+    //if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
104
+    if (xyorz == 'x' || xyorz == 'y') answer = 0.5 * (E0_Delta - Delta * (E0_Delta_eps - E0_Delta)/eps_Delta);
105
+
106
+    // Careful for z !  Hamiltonian defined as S^z S^z - 1/4, so add back N/4:
107
+    else if (xyorz == 'z') answer = (E0_Delta_eps - E0_Delta)/eps_Delta + 0.25 * N;
108
+
109
+    else JSCerror("option not implemented in X_avg.");
110
+
111
+    return(answer);
112
+  }
113
+
114
+  DP S1_sumrule_factor (char mporz, DP Delta, int N, int M, DP Chem_Pot, int iK)
115
+  {
116
+
117
+    DP X_x = X_avg ('x', Delta, N, M);
118
+    DP X_z = X_avg ('z', Delta, N, M);
119
+
120
+    DP sumrule = 0.0;
121
+
122
+    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;
123
+    //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;
124
+
125
+    else if (mporz == 'z') sumrule = iK == 0 ? 1.0 : -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
126
+
127
+    else if (mporz == 'Z') sumrule = 1.0; // partition function
128
+    else if (mporz == 'a') sumrule = 1.0;
129
+    else if (mporz == 'b') sumrule = 1.0;
130
+    else if (mporz == 'c') sumrule = 1.0;
131
+
132
+    else JSCerror("option not implemented in S1_sumrule_factor.");
133
+
134
+    //return(1.0/sumrule);
135
+    return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N
136
+  }
137
+
138
+  DP S1_sumrule_factor (char mporz, DP Delta, int N, int M, DP Chem_Pot, DP X_x, DP X_z, int iK)
139
+  {
140
+
141
+    //DP X_x = X_avg ('x', Delta, N, M);
142
+    //DP X_z = X_avg ('z', Delta, N, M);
143
+
144
+    DP sumrule = 0.0;
145
+
146
+    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;
147
+    //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;
148
+
149
+    else if (mporz == 'z') sumrule = -2.0 * X_x * (1.0 - cos((twoPI * iK)/N))/N;
150
+
151
+    else if (mporz == 'Z') sumrule = 1.0; // partition function
152
+    else if (mporz == 'a') sumrule = 1.0;
153
+    else if (mporz == 'b') sumrule = 1.0;
154
+    else if (mporz == 'c') sumrule = 1.0;
155
+
156
+    else JSCerror("option not implemented in S1_sumrule_factor.");
157
+
158
+    return(1.0/(sumrule + 1.0e-16)); // sumrule is 0 for iK == 0 or N
159
+  }
160
+
161
+
162
+  //DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& AveragingState, DP Chem_Pot, bool fixed_iK, int iKneeded)
163
+  DP Sumrule_Factor (char whichDSF, Heis_Bethe_State& AveragingState, DP Chem_Pot, int iKmin, int iKmax)
164
+  {
165
+    DP sumrule_factor = 1.0;
166
+    //if (!fixed_iK) {
167
+    if (iKmin != iKmax) {
168
+      if (whichDSF == 'Z') sumrule_factor = 1.0;
169
+      else if (whichDSF == 'm') 
170
+	sumrule_factor = 1.0/AveragingState.base.Mdown;
171
+      else if (whichDSF == 'z') sumrule_factor = 1.0/(0.25 * AveragingState.chain.Nsites);
172
+      else if (whichDSF == 'p') sumrule_factor = 1.0/(AveragingState.chain.Nsites - AveragingState.base.Mdown);
173
+      else if (whichDSF == 'a') sumrule_factor = 1.0;
174
+      else if (whichDSF == 'b') sumrule_factor = 1.0;
175
+      else if (whichDSF == 'c') sumrule_factor = 1.0;
176
+      else if (whichDSF == 'q') sumrule_factor = 1.0;
177
+
178
+      else JSCerror("whichDSF option not consistent in Sumrule_Factor");
179
+    }
180
+    //else if (fixed_iK) {
181
+    else if (iKmin == iKmax) {
182
+      if (whichDSF == 'Z') sumrule_factor = 1.0;
183
+      else if (whichDSF == 'm' || whichDSF == 'z' || whichDSF == 'p') 
184
+	//sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, iKneeded);
185
+	sumrule_factor = S1_sumrule_factor (whichDSF, AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown, Chem_Pot, iKmax);
186
+      else if (whichDSF == 'a') sumrule_factor = 1.0;
187
+      else if (whichDSF == 'b') sumrule_factor = 1.0;
188
+      else if (whichDSF == 'c') sumrule_factor = 1.0;
189
+      else if (whichDSF == 'q') sumrule_factor = 1.0;
190
+      
191
+      else JSCerror("whichDSF option not consistent in Sumrule_Factor");
192
+    }
193
+
194
+    
195
+
196
+    return(sumrule_factor);
197
+  }
198
+  
199
+
200
+  void Evaluate_F_Sumrule (string prefix, char whichDSF, const Heis_Bethe_State& AveragingState, DP Chem_Pot, int iKmin_ref, int iKmax_ref)
201
+  {
202
+
203
+    stringstream RAW_stringstream;    string RAW_string;
204
+    RAW_stringstream << prefix << ".raw";    
205
+    RAW_string = RAW_stringstream.str();    const char* RAW_Cstr = RAW_string.c_str();
206
+
207
+    stringstream FSR_stringstream;    string FSR_string;
208
+    FSR_stringstream << prefix << ".fsr";
209
+    FSR_string = FSR_stringstream.str();    const char* FSR_Cstr = FSR_string.c_str();
210
+
211
+    ifstream infile;
212
+    infile.open(RAW_Cstr);
213
+    if(infile.fail()) JSCerror("Could not open raw input file in Evaluate_F_Sumrule(Heis...).");
214
+
215
+    int iKmin = 0;
216
+    int iKmax = AveragingState.chain.Nsites;
217
+    int iKmod = AveragingState.chain.Nsites;
218
+
219
+    // We run through the data file to chech the f sumrule at each positive momenta:
220
+    //Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);  
221
+    Vect<DP> Sum_omega_MEsq(0.0, iKmax - iKmin + 1);  
222
+
223
+    DP omega, ME;
224
+    int iK, iKexc;
225
+    //int conv;
226
+    DP dev;
227
+    string label;
228
+
229
+    while (infile.peek() != EOF) {
230
+      infile >> omega >> iK >> ME >> dev >> label;
231
+      //if (iK >= iKmin && iK <= iKmax) Sum_omega_MEsq[iK - iKmin] += omega * ME * ME;
232
+      iKexc = iK;
233
+      while (iKexc > iKmax && iKexc - iKmod >= iKmin) iKexc -= iKmod;
234
+      while (iKexc < iKmin && iKexc + iKmod <= iKmax) iKexc += iKmod;
235
+      if (iKexc >= iKmin && iKexc <= iKmax) Sum_omega_MEsq[iKexc - iKmin] += omega * ME * ME;
236
+    }
237
+
238
+    infile.close();
239
+
240
+    ofstream outfile;
241
+    outfile.open(FSR_Cstr);
242
+    outfile.precision(16);
243
+
244
+    DP X_x = X_avg ('x', AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown);
245
+    DP X_z = X_avg ('z', AveragingState.chain.Delta, AveragingState.chain.Nsites, AveragingState.base.Mdown);
246
+
247
+    for (int i = iKmin; i <= iKmax; ++i) {
248
+      if (i > iKmin) outfile << endl;
249
+      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);
250
+    }
251
+
252
+    outfile.close();
253
+  }
254
+
255
+} // namespace JSC

+ 139
- 0
src/HEIS/M_vs_H.cc View File

@@ -0,0 +1,139 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c) 2006-9.
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  M_vs_H.cc
10
+
11
+Purpose:  field to and from magnetization for Heisenberg
12
+
13
+Last modified:  21/10/09
14
+
15
+
16
+***********************************************************/
17
+
18
+#include "JSC.h"
19
+
20
+namespace JSC { 
21
+
22
+  DP Ezero (DP Delta, int N, int M)
23
+  {
24
+    // Returns the energy of the ground state with M down spins
25
+
26
+    if (M < 0 || M > N/2) JSCerror("M out of bounds in Ezero.");
27
+   
28
+    DP E = -1.0; // sentinel value
29
+
30
+    if (M == 0) E = N * Delta/4.0;
31
+
32
+    else {
33
+
34
+      Heis_Chain BD1(1.0, Delta, 0.0, N);
35
+      
36
+      Vect_INT Nrapidities_groundstate(0, BD1.Nstrings);
37
+      
38
+      Nrapidities_groundstate[0] = M;
39
+      
40
+      Heis_Base baseconfig_groundstate(BD1, Nrapidities_groundstate);
41
+      
42
+      if ((Delta > 0.0) && (Delta < 1.0)) {
43
+	XXZ_Bethe_State groundstate(BD1, baseconfig_groundstate);
44
+	groundstate.Compute_All(true);
45
+	E = groundstate.E;
46
+      }
47
+      
48
+      else if (Delta == 1.0) {
49
+	XXX_Bethe_State groundstate(BD1, baseconfig_groundstate);
50
+	groundstate.Compute_All(true);
51
+	E = groundstate.E;
52
+      }
53
+      
54
+      else if (Delta > 1.0) {
55
+	XXZ_gpd_Bethe_State groundstate(BD1, baseconfig_groundstate);
56
+	groundstate.Compute_All(true);
57
+	E = groundstate.E;
58
+      }
59
+      
60
+      else JSCerror("Anisotropy out of bounds in Ezero.");
61
+    }
62
+
63
+    return(E);
64
+  }
65
+
66
+  DP H_vs_M (DP Delta, int N, int M)
67
+  {
68
+    // Assumes dE/dM = 0 = dE_0/dM + h, with dE_0/dM = E_0(M) - E_0 (M - 1)
69
+
70
+    DP H = 0.0;
71
+
72
+    if (2*M == N) H = 0.0; 
73
+
74
+    else if (Delta <= 1.0) H = Ezero (Delta, N, M - 1) - Ezero (Delta, N, M);
75
+
76
+    return(H);
77
+  }
78
+
79
+  DP HZmin (DP Delta, int N, int M, Vect_DP& Ezero_ref)
80
+  {
81
+    if (M < 0 || M > N/2 - 1) {
82
+      cout << "M = " << M << endl;
83
+      JSCerror("M out of bounds in HZmin.");    
84
+    }
85
+
86
+    if (Ezero_ref[M] == -1.0) Ezero_ref[M] = Ezero(Delta, N, M);
87
+    if (Ezero_ref[M + 1] == -1.0) Ezero_ref[M + 1] = Ezero(Delta, N, M + 1);
88
+
89
+    return(Ezero_ref[M] - Ezero_ref[M + 1]);
90
+  }
91
+
92
+  int M_vs_H (DP Delta, int N, DP HZ)
93
+  {
94
+    // Returns the value of M for given field HZ
95
+
96
+    if (HZ < 0.0) JSCerror("Please use a positive field in M_vs_H.");
97
+
98
+    else if (HZ == 0.0) return(N/2);
99
+
100
+    // Here, -1.0 is a sentinel value.
101
+    Vect_DP Ezero(-1.0, N/2 + 1);  // contains the GSE[M].
102
+
103
+    // We look for M s.t. HZmin[M] < HZ <= HZmin[M + 1]
104
+
105
+    int M_actual = N/4; // start somewhere in middle
106
+    int M_step = N/8 - 1; // step
107
+    DP HZmin_actual = 0.0;
108
+    DP HZmax_actual = 0.0;
109
+    bool M_found = false;
110
+
111
+    if (HZ >= 1.0 + Delta) M_actual = 0;  // saturation
112
+
113
+    else {
114
+      
115
+      HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
116
+      HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
117
+
118
+      while (!M_found) {
119
+
120
+	if (HZmin_actual > HZ) M_actual += M_step;
121
+	else if (HZmax_actual <= HZ) M_actual -= M_step;
122
+	
123
+	M_step = (M_step + 1)/2;
124
+
125
+	HZmin_actual = HZmin (Delta, N, M_actual, Ezero);
126
+	HZmax_actual = HZmin (Delta, N, M_actual - 1, Ezero);
127
+
128
+	M_found = (HZmin_actual < HZ && HZ <= HZmax_actual);	
129
+
130
+	//cout << "M_actual = " << M_actual << "\tM_step = " << M_step 
131
+	//   << "\tHZmin_actual = " << HZmin_actual << "\tHZmax_actual = " << HZmax_actual << "\tHZ = " << HZ << "\t" << M_found << endl;
132
+      }
133
+    }
134
+    //cout << "M found = " << M_actual << "\tHZmax = " << Ezero[M_actual] - Ezero[M_actual + 1] << "\tHZmin = " << Ezero[M_actual - 1] - Ezero[M_actual] << endl;
135
+
136
+    return(M_actual);
137
+  }
138
+
139
+}

+ 626
- 0
src/HEIS/XXX_Bethe_State.cc View File

@@ -0,0 +1,626 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  src/HEIS/XXX_Bethe_State.cc
10
+
11
+Purpose:  Defines all functions for XXX_Bethe_State
12
+
13
+******************************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+
19
+namespace JSC {
20
+
21
+  // Function prototypes
22
+
23
+  DP Theta_XXX (DP lambda, int nj, int nk);
24
+  DP ddlambda_Theta_XXX (DP lambda, int nj, int nk);
25
+
26
+  //***************************************************************************************************
27
+
28
+  // Function definitions:  class XXX_Bethe_State
29
+
30
+  XXX_Bethe_State::XXX_Bethe_State () 
31
+    : Heis_Bethe_State()
32
+  {};
33
+
34
+  XXX_Bethe_State::XXX_Bethe_State (const XXX_Bethe_State& RefState) // copy constructor
35
+    : Heis_Bethe_State(RefState)
36
+  {
37
+  }
38
+  
39
+  XXX_Bethe_State::XXX_Bethe_State (const Heis_Chain& RefChain, int M) 
40
+    : Heis_Bethe_State(RefChain, M)
41
+  {
42
+    if (RefChain.Delta != 1.0) {
43
+      cout << setprecision(16) << RefChain.Delta << endl;
44
+      JSCerror("Delta != 1.0 in XXX_Bethe_State constructor");    
45
+    }
46
+  }
47
+  
48
+  XXX_Bethe_State::XXX_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase) 
49
+    : Heis_Bethe_State(RefChain, RefBase)
50
+  {
51
+    if (RefChain.Delta != 1.0) {
52
+      cout << setprecision(16) << RefChain.Delta << endl;
53
+      JSCerror("Delta != 1.0 in XXX_Bethe_State constructor");    
54
+    }
55
+  }
56
+  /*
57
+  XXX_Bethe_State::XXX_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
58
+    : Heis_Bethe_State(RefChain, base_id_ref, type_id_ref)
59
+  {
60
+    if (RefChain.Delta != 1.0) {
61
+      cout << setprecision(16) << RefChain.Delta << endl;
62
+      JSCerror("Delta != 1.0 in XXX_Bethe_State constructor");    
63
+    }
64
+  }
65
+  */
66
+  XXX_Bethe_State& XXX_Bethe_State::operator= (const XXX_Bethe_State& RefState)
67
+  {
68
+    if (this != &RefState) {
69
+      chain = RefState.chain;
70
+      base = RefState.base;
71
+      //offsets = RefState.offsets;
72
+      Ix2 = RefState.Ix2;
73
+      lambda = RefState.lambda;
74
+      BE = RefState.BE;
75
+      diffsq = RefState.diffsq;
76
+      conv = RefState.conv;
77
+      iter = RefState.iter;
78
+      iter_Newton = RefState.iter_Newton;
79
+      E = RefState.E;
80
+      iK = RefState.iK;
81
+      K = RefState.K;
82
+      lnnorm = RefState.lnnorm;
83
+      //base_id = RefState.base_id;
84
+      //type_id = RefState.type_id;
85
+      //id = RefState.id;
86
+      //maxid = RefState.maxid;
87
+      //nparticles = RefState.nparticles;
88
+      label = RefState.label;
89
+    }
90
+    return(*this);
91
+  }
92
+
93
+  // Member functions
94
+
95
+  void XXX_Bethe_State::Set_Free_lambdas()
96
+  {
97
+    // Sets all the rapidities to the solutions of the BAEs without scattering terms
98
+
99
+    for (int i = 0; i < chain.Nstrings; ++i) {
100
+
101
+      for (int alpha = 0; alpha < base[i]; ++alpha) {
102
+
103
+	lambda[i][alpha] = chain.Str_L[i] * 0.5 * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites);
104
+
105
+      }
106
+    }
107
+    
108
+    return;
109
+  }
110
+
111
+  bool XXX_Bethe_State::Check_Admissibility(char option)
112
+  {
113
+    // This function checks the admissibility of the Ix2's of a state:  
114
+    // returns false if there are higher strings with Ix2 = 0, a totally symmetric distribution of I's at each level,
115
+    // and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE.
116
+
117
+    bool answer = true;
118
+    //int test1, test3;
119
+    Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
120
+
121
+    bool higher_string_on_zero = false;
122
+
123
+    for (int j = 0; j < chain.Nstrings; ++j) {
124
+      // The following line puts answer to true if there is at least one higher string with zero Ix2
125
+      for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] > 2) && !(chain.Str_L[j] % 2)) 
126
+	higher_string_on_zero = true;  
127
+      for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;         
128
+      // NOTE:  if base[j] == 0, Zero_at_level[j] remains false.
129
+    }
130
+
131
+    bool symmetric_state = (*this).Check_Symmetry();
132
+
133
+    bool string_coincidence = false;
134
+    // Checks that we have strings of equal length modulo 2 with Ix2 == 0, so equal rapidities, and inadmissibility
135
+    for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
136
+      for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
137
+	if (Zero_at_level[j1] && Zero_at_level[j2] && (!((chain.Str_L[j1] + chain.Str_L[j2])%2))) 
138
+	  string_coincidence = true;
139
+    }
140
+    /*
141
+    bool onep_onem_on_zero = false;
142
+    if (option == 'm') { // for Smin, we also exclude symmetric states with 1+ and 1- strings on zero
143
+      if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
144
+    }
145
+    */
146
+    answer = !(symmetric_state && (higher_string_on_zero || string_coincidence /*|| onep_onem_on_zero*/));
147
+
148
+    // Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
149
+
150
+    for (int j = 0; j < chain.Nstrings; ++j) 
151
+      for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;    
152
+
153
+    if (!answer) {
154
+      E = 0.0;
155
+      K = 0.0;
156
+      conv = 0;
157
+      iter = 0;
158
+      iter_Newton = 0;
159
+      lnnorm = -100.0;
160
+    }
161
+
162
+    return(answer);  // answer == true:  nothing wrong with this Ix2_config
163
+  }
164
+
165
+  void XXX_Bethe_State::Compute_BE (int j, int alpha)
166
+  {
167
+    // Fills in the BE members with the value of the Bethe equations.
168
+
169
+    DP sumtheta = 0.0;
170
+
171
+    sumtheta = 0.0;
172
+    for (int k = 0; k < chain.Nstrings; ++k) {
173
+      for (int beta = 0; beta < base[k]; ++beta) 
174
+	
175
+	if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
176
+	  sumtheta += atan(lambda[j][alpha] - lambda[k][beta]); 
177
+      
178
+	else sumtheta += 0.5 * Theta_XXX((lambda[j][alpha] - lambda[k][beta]), chain.Str_L[j], chain.Str_L[k]);
179
+    }
180
+    sumtheta *= 2.0;
181
+    
182
+    BE[j][alpha] = 2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
183
+  }
184
+
185
+  void XXX_Bethe_State::Compute_BE ()
186
+  {
187
+    // Fills in the BE members with the value of the Bethe equations.
188
+
189
+    DP sumtheta = 0.0;
190
+
191
+    for (int j = 0; j < chain.Nstrings; ++j) {
192
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
193
+	
194
+	sumtheta = 0.0;
195
+	for (int k = 0; k < chain.Nstrings; ++k) {
196
+	  for (int beta = 0; beta < base[k]; ++beta) 
197
+	    
198
+	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
199
+	      sumtheta += atan(lambda[j][alpha] - lambda[k][beta]); 
200
+	  
201
+	    else sumtheta += 0.5 * Theta_XXX((lambda[j][alpha] - lambda[k][beta]), chain.Str_L[j], chain.Str_L[k]);
202
+	}
203
+	sumtheta *= 2.0;
204
+	
205
+	BE[j][alpha] = 2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
206
+      }
207
+    }
208
+  }
209
+
210
+  DP XXX_Bethe_State::Iterate_BAE (int j, int alpha)
211
+  {
212
+    // Returns a new iteration value for lambda[j][alpha] given BE[j][alpha]
213
+
214
+    return(0.5 * chain.Str_L[j] * tan(0.5 * 
215
+				      //(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
216
+				      (2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - BE[j][alpha])
217
+				      ));
218
+  }
219
+
220
+  /*
221
+  void XXX_Bethe_State::Iterate_BAE ()
222
+  {
223
+    // Recalculates the rapidities by iterating Bethe equations
224
+
225
+    Lambda New_lambda(chain, base);
226
+    DP sumtheta = 0.0;
227
+    DP arg = 0.0;
228
+
229
+    for (int j = 0; j < chain.Nstrings; ++j) {
230
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
231
+
232
+	sumtheta = 0.0;
233
+	for (int k = 0; k < chain.Nstrings; ++k) {
234
+	  for (int beta = 0; beta < base[k]; ++beta) 
235
+
236
+	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
237
+	      sumtheta += atan(lambda[j][alpha] - lambda[k][beta]); 
238
+
239
+	    else sumtheta += 0.5 * Theta_XXX(lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k]);
240
+	}
241
+	sumtheta *= 2.0;
242
+
243
+	New_lambda[j][alpha] = 0.5 * chain.Str_L[j] * tan((PI * 0.5 * Ix2[j][alpha] + 0.5 * sumtheta)/chain.Nsites);
244
+
245
+      }
246
+    }
247
+
248
+    DP New_diffsq = 0.0;
249
+
250
+    for (int j = 0; j < chain.Nstrings; ++j) {
251
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
252
+	New_diffsq += pow(New_lambda[j][alpha] - lambda[j][alpha], 2.0);
253
+	lambda[j][alpha] = 1.0 * New_lambda[j][alpha] + 0.0 * lambda[j][alpha];
254
+      }
255
+    }
256
+
257
+    diffsq = New_diffsq;
258
+    iter++;
259
+
260
+    return;
261
+  }
262
+  */
263
+  /*
264
+  void XXX_Bethe_State::Iterate_BAE_Newton ()
265
+  {
266
+    // does one step of a Newton method on the rapidities...
267
+
268
+    Vect_DP RHSBAE (0.0, base.Nraptot);  // contains RHS of BAEs
269
+    Vect_CX dlambda (0.0, base.Nraptot);  // contains delta lambda computed from Newton's method
270
+    SQMat_CX Gaudin (0.0, base.Nraptot);
271
+    Vect_INT indx (base.Nraptot);
272
+    DP sumtheta = 0.0;
273
+    DP arg = 0.0;
274
+    DP fn_arg = 0.0;
275
+    DP olddiffsq = diffsq;
276
+
277
+    // Compute the RHS of the BAEs:
278
+
279
+    int index = 0;
280
+
281
+    for (int j = 0; j < chain.Nstrings; ++j) {
282
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
283
+
284
+	sumtheta = 0.0;
285
+	for (int k = 0; k < chain.Nstrings; ++k) {
286
+	  for (int beta = 0; beta < base[k]; ++beta) 
287
+
288
+	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
289
+	      sumtheta += atan(lambda[j][alpha] - lambda[k][beta]); 
290
+
291
+	    else sumtheta += 0.5 * Theta_XXX((lambda[j][alpha] - lambda[k][beta]), chain.Str_L[j], chain.Str_L[k]);
292
+	}
293
+	sumtheta *= 2.0;
294
+
295
+	RHSBAE[index] = chain.Nsites * 2.0 * atan(2.0 * lambda[j][alpha]/chain.Str_L[j]) - sumtheta - PI*Ix2[j][alpha];
296
+	index++;
297
+      }
298
+    }
299
+    
300
+    (*this).Build_Reduced_Gaudin_Matrix (Gaudin);
301
+
302
+    for (int i = 0; i < base.Nraptot; ++i) dlambda[i] = - RHSBAE[i];
303
+
304
+    DP d;
305
+    ludcmp_CX (Gaudin, indx, d);
306
+    lubksb_CX (Gaudin, indx, dlambda);
307
+
308
+    diffsq = 0.0;
309
+    for (int i = 0; i < base.Nraptot; ++i) diffsq += norm(dlambda[i]);
310
+
311
+    // if we've converged, calculate the norm here, since the work has been done...
312
+
313
+    if (diffsq < chain.prec) {
314
+      lnnorm = 0.0;
315
+      for (int j = 0; j < base.Nraptot; j++) lnnorm += log(abs(Gaudin[j][j]));
316
+    }
317
+
318
+    index = 0;
319
+    for (int j = 0; j < chain.Nstrings; ++j) {
320
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
321
+	lambda[j][alpha] += real(dlambda[index]);
322
+	index++;
323
+      }
324
+    }
325
+
326
+    iter_Newton++;
327
+
328
+    return;
329
+  }
330
+  */
331
+  bool XXX_Bethe_State::Check_Rapidities()
332
+  {
333
+    bool nonan = true;
334
+
335
+    for (int j = 0; j < chain.Nstrings; ++j)
336
+      for (int alpha = 0; alpha < base[j]; ++alpha) nonan *= !is_nan(lambda[j][alpha]);
337
+    
338
+    return nonan;
339
+  }
340
+
341
+  DP XXX_Bethe_State::String_delta ()
342
+  {
343
+    // Computes the sum of absolute value of \delta^{a, a+1} in string hypothesis, for a given Bethe eigenstate
344
+
345
+    DP delta = 0.0;
346
+
347
+    int occupied_strings = 0;
348
+    for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
349
+
350
+    //if ((*this).conv == 0) delta = 1.0;
351
+
352
+    if (occupied_strings == 0) delta = 0.0;
353
+
354
+    else {
355
+
356
+      Vect_DP ln_deltadiff(0.0, 1000);  // contains ln |delta^{a, a+1}|
357
+      Vect_DP deltadiff(0.0, 1000);  // contains |delta^{a, a+1}|
358
+
359
+      complex<DP> log_BAE_reg = 0.0;
360
+
361
+      for (int j = 0; j < (*this).chain.Nstrings; ++j) {
362
+	for (int alpha = 0; alpha < (*this).base[j]; ++alpha) {
363
+
364
+	  ln_deltadiff = 0.0;
365
+	      
366
+	  for (int a = 1; a <= (*this).chain.Str_L[j]; ++a) {
367
+	    
368
+	    if ((*this).chain.Str_L[j] > 1) {  // else the BAE are already 1
369
+
370
+	      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))
371
+							 /((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)));
372
+	      
373
+	      for (int k = 0; k < (*this).chain.Nstrings; ++k) 
374
+		for (int beta = 0; beta < (*this).base[k]; ++beta) 
375
+		  for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
376
+		    if ((j != k) || (alpha != beta) || (a != b - 1)) 
377
+
378
+		      log_BAE_reg += log((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
379
+				      - ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
380
+					 ) - II );
381
+		    
382
+		    if ((j != k) || (alpha != beta) || (a != b + 1)) 
383
+
384
+		      log_BAE_reg -= log(((*this).lambda[j][alpha] + 0.5 * II * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a )
385
+				       ) 
386
+				      - ((*this).lambda[k][beta] + 0.5 * II * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
387
+					 ) + II );
388
+		  }
389
+
390
+	      // The regular LHS of BAE is now defined.  Now sum up the deltas...
391
+	      
392
+	      if (a == 1) ln_deltadiff[0] = - real(log_BAE_reg);
393
+	      
394
+	      else if (a < (*this).chain.Str_L[j]) ln_deltadiff[a - 1] = ln_deltadiff[a-2] - real(log_BAE_reg);
395
+	      
396
+	      else if (a == (*this).chain.Str_L[j]) ln_deltadiff[a-1] = real(log_BAE_reg);
397
+
398
+	    } // if ((*this).chain.Str_L[j] > 1)
399
+	    
400
+	  } // for (int a = 1; ...
401
+
402
+	  for (int a = 0; a < (*this).chain.Str_L[j]; ++a) {
403
+	    deltadiff[a] = ln_deltadiff[a] != 0.0 ? exp(ln_deltadiff[a]) : 0.0;
404
+	    delta += fabs(deltadiff[a]);
405
+	  }  
406
+	      
407
+	} // alpha sum
408
+      } // j sum
409
+
410
+      if (is_nan(delta)) delta = 1.0; // sentinel
411
+
412
+    } // else
413
+
414
+    return delta;
415
+  }
416
+
417
+
418
+  void XXX_Bethe_State::Compute_Energy ()
419
+  {
420
+    DP sum = 0.0;
421
+    
422
+    for (int j = 0; j < chain.Nstrings; ++j) {
423
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
424
+	sum += chain.Str_L[j] / ( 4.0 * lambda[j][alpha] * lambda[j][alpha] + chain.Str_L[j] * chain.Str_L[j]);
425
+      }
426
+    }
427
+
428
+    sum *= - chain.J * 2.0;
429
+    
430
+    E = sum;
431
+
432
+    return;
433
+  }
434
+
435
+  /*
436
+  void XXX_Bethe_State::Compute_Momentum ()
437
+  {
438
+    int sum_Ix2 = 0;
439
+    DP sum_M = 0.0;
440
+
441
+    for (int j = 0; j < chain.Nstrings; ++j) {
442
+      sum_M += base[j];
443
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
444
+	sum_Ix2 += Ix2[j][alpha];
445
+      }
446
+    }
447
+
448
+    iK = (chain.Nsites/2) * int(sum_M) - (sum_Ix2/2);
449
+
450
+    while (iK >= chain.Nsites) iK -= chain.Nsites;
451
+    while (iK < 0) iK += chain.Nsites;
452
+
453
+    K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
454
+
455
+    while (K >= 2.0*PI) K -= 2.0*PI;
456
+    while (K < 0.0) K += 2.0*PI;
457
+
458
+    return;
459
+  }
460
+  */
461
+
462
+  void XXX_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
463
+  {
464
+
465
+    if (Gaudin_Red.size() != base.Nraptot) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
466
+
467
+    int index_jalpha;
468
+    int index_kbeta;
469
+
470
+    DP sum_hbar_XXX = 0.0;
471
+
472
+    index_jalpha = 0;
473
+    for (int j = 0; j < chain.Nstrings; ++j) {
474
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
475
+	index_kbeta = 0;
476
+	for (int k = 0; k < chain.Nstrings; ++k) {
477
+	  for (int beta = 0; beta < base[k]; ++beta) {
478
+
479
+	    if ((j == k) && (alpha == beta)) {
480
+
481
+	      sum_hbar_XXX = 0.0;
482
+
483
+	      for (int kp = 0; kp < chain.Nstrings; ++kp) {
484
+		for (int betap = 0; betap < base[kp]; ++betap) {
485
+		  if (!((j == kp) && (alpha == betap))) 
486
+		    sum_hbar_XXX 
487
+		      += ddlambda_Theta_XXX (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp]);
488
+		}
489
+	      }
490
+
491
+	      Gaudin_Red[index_jalpha][index_kbeta] 
492
+		= complex<DP> ( chain.Nsites * chain.Str_L[j]/(lambda[j][alpha] * lambda[j][alpha] + 0.25 * chain.Str_L[j] * chain.Str_L[j]) 
493
+				- sum_hbar_XXX);
494
+	    }
495
+
496
+	    else {
497
+	      if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
498
+		Gaudin_Red[index_jalpha][index_kbeta] = 
499
+		  complex<DP> ( 2.0/(pow(lambda[j][alpha] - lambda[k][beta], 2.0) + 1.0));
500
+
501
+	      else 
502
+		Gaudin_Red[index_jalpha][index_kbeta] = 
503
+		  complex<DP> (ddlambda_Theta_XXX (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], chain.Str_L[k]));
504
+	    }
505
+	    index_kbeta++;
506
+	  }
507
+	}
508
+	index_jalpha++;
509
+      }
510
+    }
511
+    return;
512
+  }
513
+
514
+  bool XXX_Bethe_State::Check_Finite_rap ()
515
+  {
516
+    bool answer = true;
517
+
518
+    for (int j = 0; j < chain.Nstrings; ++j) {
519
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
520
+	if (fabs(lambda[j][alpha]) > 1.0e6) answer = false;
521
+      }
522
+    }
523
+    
524
+    return(answer);
525
+  }
526
+
527
+  // ****************************************************************************************************
528
+
529
+  // non-member functions
530
+
531
+  DP Theta_XXX (DP lambda, int nj, int nk)
532
+  {
533
+    DP result;
534
+
535
+    if ((nj == 1) && (nk == 1)) result = 2.0 * atan(lambda);
536
+    
537
+    else {
538
+
539
+      result = (nj == nk) ? 0.0 : 2.0 * atan(2.0 * lambda/fabs(nj - nk));
540
+
541
+      for (int a = 1; a < JSC::min(nj, nk); ++a) result += 4.0 * atan(2.0 * lambda/(fabs(nj - nk) + 2*a));
542
+
543
+      result += 2.0 * atan(2.0 * lambda/(nj + nk));
544
+    }
545
+
546
+    return (result);
547
+  }
548
+
549
+  DP ddlambda_Theta_XXX (DP lambda, int nj, int nk)
550
+  {
551
+    int n = abs(nj - nk);
552
+
553
+    DP result = (nj == nk) ? 0.0 : DP(n)/(lambda * lambda + 0.25 * n * n);
554
+
555
+    for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * (n + 2.0*a) 
556
+      / (lambda * lambda + 0.25 * (n + 2.0*a) * (n + 2.0*a));
557
+
558
+    result += DP(nj + nk)/(lambda * lambda + 0.25 * (nj + nk) * (nj + nk));
559
+
560
+    return (result);
561
+  }
562
+  /*
563
+  DP ddlambda_Theta_XXX (DP lambda, int nj, int nk)
564
+  {
565
+    DP result = (nj == nk) ? 0.0 : DP(nj - nk)/(lambda * lambda + 0.25 * (nj - nk) * (nj - nk));
566
+
567
+    for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * (nj - nk + 2.0*a) * (nj - nk + 2.0*a) 
568
+      / (lambda * lambda + 0.25 * (nj - nk + 2.0*a) * (nj - nk + 2.0*a));
569
+
570
+    result += DP(nj + nk)/(lambda * lambda + 0.25 * (nj + nk) * (nj + nk));
571
+
572
+    return (result);
573
+  }
574
+  */
575
+
576
+  XXX_Bethe_State Add_Particle_at_Center (const XXX_Bethe_State& RefState)
577
+  {
578
+    if (2*RefState.base.Mdown == RefState.chain.Nsites) 
579
+      JSCerror("Trying to add a down spin to a zero-magnetized chain in Add_Particle_at_Center.");
580
+
581
+    Vect<int> newM = RefState.base.Nrap;
582
+    newM[0] = newM[0] + 1;
583
+
584
+    Heis_Base newBase (RefState.chain, newM);
585
+
586
+    XXX_Bethe_State ReturnState (RefState.chain, newBase);
587
+
588
+    for (int il = 1; il < RefState.chain.Nstrings; ++il)
589
+      for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha) 
590
+	ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
591
+
592
+    // Add a quantum number in middle (explicitly: to right of index M[0]/2) 
593
+    // and shift quantum numbers by half-integer away from added one:
594
+    ReturnState.Ix2[0][RefState.base.Nrap[0]/2] = RefState.Ix2[0][RefState.base.Nrap[0]/2] - 1;
595
+    for (int i = 0; i < RefState.base.Nrap[0] + 1; ++i)
596
+      ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] = RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
597
+
598
+    return(ReturnState);
599
+  }
600
+
601
+
602
+  XXX_Bethe_State Remove_Particle_at_Center (const XXX_Bethe_State& RefState)
603
+  {
604
+    if (RefState.base.Nrap[0] == 0)
605
+      JSCerror("Trying to remove a down spin in an empty Nrap[0] state.");
606
+
607
+    Vect<int> newM = RefState.base.Nrap;
608
+    newM[0] = newM[0] - 1;
609
+
610
+    Heis_Base newBase (RefState.chain, newM);
611
+
612
+    XXX_Bethe_State ReturnState (RefState.chain, newBase);
613
+
614
+    for (int il = 1; il < RefState.chain.Nstrings; ++il)
615
+      for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha) 
616
+	ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
617
+
618
+    // Remove midmost and shift quantum numbers by half-integer towards removed one:
619
+    for (int i = 0; i < RefState.base.Nrap[0]-1; ++i)
620
+      ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
621
+
622
+    return(ReturnState);
623
+    }
624
+
625
+  
626
+} // namespace JSC

+ 646
- 0
src/HEIS/XXZ_Bethe_State.cc View File

@@ -0,0 +1,646 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  src/HEIS/XXZ_Bethe_State.cc
10
+
11
+Purpose:  Defines all functions for XXZ_Bethe_State
12
+
13
+******************************************************************/
14
+
15
+#include "JSC.h"
16
+
17
+using namespace std;
18
+
19
+namespace JSC {
20
+
21
+  // Function prototypes
22
+
23
+  inline DP fbar_XXZ (DP lambda, int par, DP tannzetaover2);
24
+  DP Theta_XXZ (DP lambda, int nj, int nk, int parj, int park, DP* tannzetaover2);
25
+  DP hbar_XXZ (DP lambda, int n, int par, DP* si_n_anis_over_2);
26
+  DP ddlambda_Theta_XXZ (DP lambda, int nj, int nk, int parj, int park, DP* si_n_anis_over_2);
27
+
28
+
29
+  //***************************************************************************************************
30
+
31
+  // Function definitions:  class XXZ_Bethe_State
32
+
33
+  XXZ_Bethe_State::XXZ_Bethe_State () 
34
+    : Heis_Bethe_State(), sinhlambda(Lambda(chain, 1)), coshlambda(Lambda(chain, 1)), tanhlambda(Lambda(chain, 1)) 
35
+  {};
36
+
37
+  XXZ_Bethe_State::XXZ_Bethe_State (const XXZ_Bethe_State& RefState) // copy constructor
38
+    : Heis_Bethe_State(RefState), sinhlambda(Lambda(RefState.chain, RefState.base)), coshlambda(Lambda(RefState.chain, RefState.base)), 
39
+      tanhlambda(Lambda(RefState.chain, RefState.base))
40
+  {
41
+    // copy arrays into new ones
42
+
43
+    //cout << "Calling XXZ state copy constructor." << endl;
44
+    for (int j = 0; j < RefState.chain.Nstrings; ++j) {
45
+      for (int alpha = 0; alpha < RefState.base[j]; ++j) {
46
+	sinhlambda[j][alpha] = RefState.sinhlambda[j][alpha];
47
+	coshlambda[j][alpha] = RefState.coshlambda[j][alpha];
48
+	tanhlambda[j][alpha] = RefState.tanhlambda[j][alpha];
49
+      }
50
+    }
51
+    //cout << "Done calling XXZ state copy constructor." << endl;
52
+  }
53
+  
54
+  XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, int M) 
55
+    : Heis_Bethe_State(RefChain, M), 
56
+      sinhlambda(Lambda(RefChain, M)), coshlambda(Lambda(RefChain, M)), tanhlambda(Lambda(RefChain, M))
57
+  {
58
+    //cout << "Here in XXZ BS constructor." << endl;
59
+    //cout << (*this).lambda[0][0] << endl;
60
+    //cout << "OK" << endl;
61
+    if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) JSCerror("Delta out of range in XXZ_Bethe_State constructor");    
62
+  }
63
+  
64
+  XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase) 
65
+    : Heis_Bethe_State(RefChain, RefBase), 
66
+      sinhlambda(Lambda(RefChain, RefBase)), coshlambda(Lambda(RefChain, RefBase)), tanhlambda(Lambda(RefChain, RefBase))
67
+  {
68
+    if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) JSCerror("Delta out of range in XXZ_Bethe_State constructor");    
69
+  }
70
+  /*
71
+  XXZ_Bethe_State::XXZ_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
72
+    : Heis_Bethe_State(RefChain, base_id_ref, type_id_ref),
73
+      sinhlambda(Lambda(chain, base)), coshlambda(Lambda(chain, base)), tanhlambda(Lambda(chain, base))
74
+  {
75
+    if ((RefChain.Delta <= -1.0) || (RefChain.Delta >= 1.0)) JSCerror("Delta out of range in XXZ_Bethe_State constructor");    
76
+  }
77
+  */
78
+
79
+  XXZ_Bethe_State& XXZ_Bethe_State::operator= (const XXZ_Bethe_State& RefState)
80
+  {
81
+    if (this != &RefState) {
82
+      chain = RefState.chain;
83
+      base = RefState.base;
84
+      //offsets = RefState.offsets;
85
+      Ix2 = RefState.Ix2;
86
+      lambda = RefState.lambda;
87
+      BE = RefState.BE;
88
+      diffsq = RefState.diffsq;
89
+      conv = RefState.conv;
90
+      iter = RefState.iter;
91
+      iter_Newton = RefState.iter_Newton;
92
+      E = RefState.E;
93
+      iK = RefState.iK;
94
+      K = RefState.K;
95
+      lnnorm = RefState.lnnorm;
96
+      //base_id = RefState.base_id;
97
+      //type_id = RefState.type_id;
98
+      //id = RefState.id;
99
+      //maxid = RefState.maxid;
100
+      //nparticles = RefState.nparticles;
101
+      label = RefState.label;
102
+
103
+      sinhlambda = RefState.sinhlambda;
104
+      coshlambda = RefState.coshlambda;
105
+      tanhlambda = RefState.tanhlambda;
106
+    }
107
+    return(*this);
108
+  }
109
+
110
+  // Member functions
111
+
112
+  void XXZ_Bethe_State::Set_Free_lambdas()
113
+  {
114
+    // Sets all the rapidities to the solutions of the BAEs without scattering terms
115
+
116
+    DP x = 0.0;
117
+    for (int i = 0; i < chain.Nstrings; ++i) {
118
+
119
+      for (int alpha = 0; alpha < base[i]; ++alpha) {
120
+
121
+	if (chain.par[i] == 1) {
122
+	  //lambda[i][alpha] = atanh(tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites));
123
+	  x = tan(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites);
124
+	  lambda[i][alpha] = atanh(x/sqrt(1.0 + x*x)); // lambda then always initiated real
125
+	}
126
+
127
+	else if (chain.par[i] == -1) {
128
+	  //lambda[i][alpha] = atanh(-tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis));
129
+	  x = -tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)/tan(chain.Str_L[i] * 0.5 * chain.anis);
130
+	  lambda[i][alpha] = atanh(x/sqrt(1.0 + x*x)); // lambda then always initiated real
131
+	}
132
+
133
+	else JSCerror("Invalid parities in Set_Free_lambdas.");
134
+	//cout << tan(chain.Str_L[i] * 0.5 * chain.anis) << endl;
135
+	//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;
136
+
137
+      }
138
+    }
139
+    
140
+    return;
141
+  }
142
+
143
+  void XXZ_Bethe_State::Compute_sinhlambda()
144
+  {
145
+    for (int j = 0; j < chain.Nstrings; ++j) {
146
+
147
+      for (int alpha = 0; alpha < base[j]; ++alpha) sinhlambda[j][alpha] = sinh(lambda[j][alpha]);
148
+    }
149
+    return;
150
+  }
151
+
152
+  void XXZ_Bethe_State::Compute_coshlambda()
153
+  {
154
+    for (int j = 0; j < chain.Nstrings; ++j) {
155
+
156
+      for (int alpha = 0; alpha < base[j]; ++alpha) coshlambda[j][alpha] = cosh(lambda[j][alpha]);
157
+    }
158
+    return;
159
+  }
160
+
161
+  void XXZ_Bethe_State::Compute_tanhlambda()
162
+  {
163
+    for (int j = 0; j < chain.Nstrings; ++j) {
164
+
165
+      for (int alpha = 0; alpha < base[j]; ++alpha) tanhlambda[j][alpha] = tanh(lambda[j][alpha]);
166
+    }
167
+    return;
168
+  }
169
+
170
+  bool XXZ_Bethe_State::Check_Admissibility(char option)
171
+  {
172
+    // This function checks the admissibility of the Ix2's of a state:  
173
+    // returns false if there are higher strings with Ix2 = 0, a totally symmetric distribution of I's at each level,
174
+    // and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE.
175
+
176
+    bool answer = true;
177
+    Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
178
+
179
+    bool higher_string_on_zero = false;
180
+    for (int j = 0; j < chain.Nstrings; ++j) {
181
+      // The following line puts answer to true if there is at least one higher string with zero Ix2
182
+      for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] >= 2) /*&& !(chain.Str_L[j] % 2)*/) 
183
+	higher_string_on_zero = true;  
184
+      for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;         
185
+      // NOTE:  if base[j] == 0, Zero_at_level[j] remains false.
186
+    }
187
+
188
+    // check symmetry of Ix2 at each level, if there exists a potentially risky Ix2...
189
+
190
+    bool symmetric_state = (*this).Check_Symmetry();
191
+
192
+    bool string_coincidence = false;
193
+    for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
194
+      for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
195
+	if (Zero_at_level[j1] && Zero_at_level[j2] && (chain.par[j1] == chain.par[j2]) && (!((chain.Str_L[j1] + chain.Str_L[j2])%2))) 
196
+	  string_coincidence = true;
197
+    }
198
+
199
+    bool M_odd_and_onep_on_zero = false;
200
+    if (option == 'z') { // for Sz, if M is odd, exclude symmetric states with a 1+ on zero 
201
+                         // (zero rapidities in left and right states, so FF det not defined).
202
+      bool is_ground_state = base.Nrap[0] == base.Mdown && Ix2[0][0] == -(base.Mdown - 1) && Ix2[0][base.Mdown-1] == base.Mdown - 1;
203
+      if (Zero_at_level[0] && (base.Mdown % 2) && !is_ground_state) M_odd_and_onep_on_zero = true;
204
+    }
205
+
206
+    bool onep_onem_on_zero = false;
207
+    if (option == 'm' || option == 'p') { // for Smin, we also exclude symmetric states with 1+ and 1- strings on zero
208
+      if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
209
+    }
210
+
211
+    answer = !(symmetric_state && (higher_string_on_zero || string_coincidence || onep_onem_on_zero || M_odd_and_onep_on_zero));
212
+
213
+    // Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
214
+
215
+    for (int j = 0; j < chain.Nstrings; ++j) 
216
+      for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;    
217
+
218
+    if (!answer) {
219
+      E = 0.0;
220
+      K = 0.0;
221
+      conv = 0;
222
+      iter = 0;
223
+      iter_Newton = 0;
224
+      lnnorm = -100.0;
225
+    }
226
+
227
+    return(answer);  // answer == true:  nothing wrong with this Ix2_config
228
+  }
229
+
230
+  void XXZ_Bethe_State::Compute_BE (int j, int alpha)
231
+  {
232
+    tanhlambda[j][alpha] = tanh(lambda[j][alpha]);
233
+
234
+    DP sumtheta = 0.0;
235
+
236
+    for (int k = 0; k < chain.Nstrings; ++k) 
237
+      for (int beta = 0; beta < base[k]; ++beta) {
238
+	if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
239
+	  sumtheta += (chain.par[j] == chain.par[k]) 
240
+	    ? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2])) 
241
+	    : - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ; 
242
+	else sumtheta += 0.5 * Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]), 
243
+					 chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
244
+      }
245
+    sumtheta *= 2.0;
246
+    
247
+    BE[j][alpha] = ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) 
248
+		    : -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
249
+
250
+   }
251
+
252
+  void XXZ_Bethe_State::Compute_BE ()
253
+  {
254
+    // Fills in the BE members with the value of the Bethe equations.
255
+
256
+    (*this).Compute_tanhlambda();
257
+
258
+    DP sumtheta = 0.0;
259
+
260
+    for (int j = 0; j < chain.Nstrings; ++j) 
261
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
262
+	
263
+	sumtheta = 0.0;
264
+	for (int k = 0; k < chain.Nstrings; ++k) 
265
+	  for (int beta = 0; beta < base[k]; ++beta) {
266
+	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
267
+	      sumtheta += (chain.par[j] == chain.par[k]) 
268
+		? atan((tanhlambda[j][alpha] - tanhlambda[k][beta])/((1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2])) 
269
+		: - atan(((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ; 
270
+	    else sumtheta += 0.5 * Theta_XXZ((tanhlambda[j][alpha] - tanhlambda[k][beta])/(1.0 - tanhlambda[j][alpha] * tanhlambda[k][beta]), 
271
+					     chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
272
+	  }
273
+	sumtheta *= 2.0;
274
+	
275
+	BE[j][alpha] = ((chain.par[j] == 1) ? 2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) 
276
+			: -2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]])) - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
277
+
278
+	//if (is_nan(BE[j][alpha])) cout << "BE nan: " << j << "\t" << alpha << "\t" << lambda[j][alpha] << "\t" << tanhlambda[j][alpha] << endl;
279
+      }
280
+  }
281
+
282
+  DP XXZ_Bethe_State::Iterate_BAE (int j, int alpha)
283
+  {
284
+    // Returns a new iteration value for lambda[j][alpha] given tanhlambda and BE Lambdas 
285
+    // Assumes that tanhlambda[][] and BE[][] have been computed.
286
+
287
+    DP new_lambda = 0.0;
288
+    DP arg = 0.0;
289
+
290
+    if (chain.par[j] == 1) arg = chain.ta_n_anis_over_2[chain.Str_L[j]] 
291
+      * tan(0.5 * 
292
+	    //(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
293
+	    (2.0 * atan(tanhlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha])
294
+	    );
295
+    
296
+    else if (chain.par[j] == -1) arg = -tan(0.5 * 
297
+					    //(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites)
298
+					    (-2.0 * atan(tanhlambda[j][alpha] * chain.ta_n_anis_over_2[chain.Str_L[j]]) - BE[j][alpha]))
299
+      /chain.ta_n_anis_over_2[chain.Str_L[j]];
300
+    
301
+    if (fabs(arg) < 1.0) {
302
+      new_lambda = atanh(arg);
303
+    }
304
+    
305
+    else {
306
+      new_lambda = lambda[j][alpha];  // back to drawing board...
307
+      int block = 0;  // counter to prevent runaway while loop 
308
+      DP new_tanhlambda = 0.0;
309
+      DP sumtheta = 0.0;
310
+      arg = 10.0; // reset value to start while loop  
311
+      while ((fabs(arg) > 1.0) && (block++ < 100)) {  // recompute the diverging root on its own...
312
+	new_lambda *= 1.01; // try to go slowly towards infinity...
313
+	new_tanhlambda = tanh(new_lambda);
314
+	sumtheta = 0.0;
315
+	for (int k = 0; k < chain.Nstrings; ++k) {
316
+	  for (int beta = 0; beta < base[k]; ++beta) 
317
+	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
318
+	      sumtheta += (chain.par[j] == chain.par[k]) 
319
+		? atan((new_tanhlambda - tanhlambda[k][beta])/((1.0 - new_tanhlambda * tanhlambda[k][beta]) * chain.ta_n_anis_over_2[2])) 
320
+		: - atan(((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta])) * chain.ta_n_anis_over_2[2]) ; 
321
+	    else sumtheta += 0.5 * Theta_XXZ((new_tanhlambda - tanhlambda[k][beta])/(1.0 - new_tanhlambda * tanhlambda[k][beta]), 
322
+					     chain.Str_L[j], chain.Str_L[k], chain.par[j], chain.par[k], chain.ta_n_anis_over_2);
323
+	}
324
+	sumtheta *= 2.0;
325
+	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);
326
+	
327
+	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]];
328
+	
329
+	else JSCerror("Invalid parities in Iterate_BAE.");
330
+
331
+      }
332
+      
333
+      if (fabs(arg) < 1.0) {
334
+	new_lambda = atanh(arg);
335
+      }
336
+      
337
+      //else cout << "Rapidity blows up !\t" << lambda[j][alpha] << "\t" << new_lambda << endl;
338
+    } // else
339
+
340
+    return(new_lambda);
341
+  }
342
+
343
+  bool XXZ_Bethe_State::Check_Rapidities()
344
+  {
345
+    bool nonan = true;
346
+
347
+    for (int j = 0; j < chain.Nstrings; ++j)
348
+      for (int alpha = 0; alpha < base[j]; ++alpha) nonan *= !is_nan(lambda[j][alpha]);
349
+    
350
+    return nonan;
351
+  }
352
+
353
+  DP XXZ_Bethe_State::String_delta ()
354
+  {
355
+    // Computes the sum of absolute value of \delta^{a, a+1} in string hypothesis, for a given bethe eigenstate
356
+
357
+    DP delta = 0.0;
358
+
359
+    int occupied_strings = 0;
360
+    for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
361
+
362
+    //if ((*this).conv == 0) delta = 1.0;
363
+    
364
+    if (occupied_strings == 0) delta = 0.0; 
365
+
366
+    else {
367
+
368
+      Vect_DP ln_deltadiff(0.0, 1000);  // contains ln |delta^{a, a+1}|
369
+      Vect_DP deltadiff(0.0, 1000);  // contains |delta^{a, a+1}|
370
+
371
+      complex<DP> log_BAE_reg = 0.0;
372
+      
373
+      for (int j = 0; j < (*this).chain.Nstrings; ++j) {
374
+	for (int alpha = 0; alpha < (*this).base[j]; ++alpha) {
375
+
376
+	  ln_deltadiff = 0.0;
377
+	      
378
+	  for (int a = 1; a <= (*this).chain.Str_L[j]; ++a) {
379
+	    
380
+	    if ((*this).chain.Str_L[j] > 1) {  // else the BAE are already 1
381
+
382
+	      log_BAE_reg = DP((*this).chain.Nsites) * log(sinh((*this).lambda[j][alpha] 
383
+							   + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0)
384
+				 + 0.25 * II * PI * (1.0 - (*this).chain.par[j]))
385
+			    /sinh((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)
386
+				  + 0.25 * II * PI * (1.0 - (*this).chain.par[j])));
387
+	      
388
+	      for (int k = 0; k < (*this).chain.Nstrings; ++k) 
389
+		for (int beta = 0; beta < (*this).base[k]; ++beta) 
390
+		  for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
391
+		    if ((j != k) || (alpha != beta) || (a != b - 1)) 
392
+
393
+		      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 )
394
+				       + 0.25 * II * PI * (1.0 - (*this).chain.par[j])) 
395
+				      - ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
396
+					 + 0.25 * II * PI * (1.0 - (*this).chain.par[k])) - II * (*this).chain.anis));
397
+		    
398
+		    if ((j != k) || (alpha != beta) || (a != b + 1)) 
399
+
400
+		      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 )
401
+				       + 0.25 * II * PI * (1.0 - (*this).chain.par[j])) 
402
+				      - ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )
403
+					 + 0.25 * II * PI * (1.0 - (*this).chain.par[k])) + II * (*this).chain.anis));
404
+		  }
405
+
406
+	      // The regular LHS of BAE is now defined.  Now sum up the deltas...
407
+	      
408
+	      if (a == 1) ln_deltadiff[0] = - real(log_BAE_reg);
409
+	      
410
+	      else if (a < (*this).chain.Str_L[j]) ln_deltadiff[a - 1] = ln_deltadiff[a-2] - real(log_BAE_reg);
411
+	      
412
+	      else if (a == (*this).chain.Str_L[j]) ln_deltadiff[a-1] = real(log_BAE_reg);
413
+
414
+	    } // if ((*this).chain.Str_L[j] > 1)
415
+	    
416
+	  } // for (int a = 1; ...
417
+
418
+	  for (int a = 0; a < (*this).chain.Str_L[j]; ++a) {
419
+	    deltadiff[a] = ln_deltadiff[a] != 0.0 ? exp(ln_deltadiff[a]) : 0.0;
420
+	    delta += fabs(deltadiff[a]);
421
+	  }  
422
+
423
+	} // alpha sum
424
+      } // j sum
425
+
426
+      if (is_nan(delta)) delta = 1.0; // sentinel
427
+
428
+    } // else
429
+
430
+    return delta;
431
+  }
432
+
433
+
434
+  void XXZ_Bethe_State::Compute_Energy ()
435
+  {
436
+    DP sum = 0.0;
437
+    
438
+    for (int j = 0; j < chain.Nstrings; ++j) {
439
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
440
+	sum += sin(chain.Str_L[j] * chain.anis) / (chain.par[j] * cosh(2.0 * lambda[j][alpha]) - cos(chain.Str_L[j] * chain.anis));
441
+      }
442
+    }
443
+
444
+    sum *= - chain.J * sin(chain.anis);
445
+    
446
+    E = sum;
447
+
448
+    return;
449
+  }
450
+
451
+  /*
452
+  void XXZ_Bethe_State::Compute_Momentum ()
453
+  {
454
+    int sum_Ix2 = 0;
455
+    DP sum_M = 0.0;
456
+
457
+    for (int j = 0; j < chain.Nstrings; ++j) {
458
+      sum_M += 0.5 * (1.0 + chain.par[j]) * base[j];
459
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
460
+	sum_Ix2 += Ix2[j][alpha];
461
+      }
462
+    }
463
+
464
+    iK = (chain.Nsites/2) * int(sum_M + 0.1) - (sum_Ix2/2);  // + 0.1:  for safety...
465
+
466
+    while (iK >= chain.Nsites) iK -= chain.Nsites;
467
+    while (iK < 0) iK += chain.Nsites;
468
+
469
+    K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
470
+
471
+    while (K >= 2.0*PI) K -= 2.0*PI;
472
+    while (K < 0.0) K += 2.0*PI;
473
+
474
+    return;
475
+  }
476
+  */
477
+  void XXZ_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
478
+  {
479
+
480
+    if (Gaudin_Red.size() != base.Nraptot) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
481
+
482
+    int index_jalpha;
483
+    int index_kbeta;
484
+
485
+    DP sum_hbar_XXZ = 0.0;
486
+
487
+    DP sinzetasq = pow(sin(chain.anis), 2.0);
488
+
489
+    (*this).Compute_sinhlambda();
490
+    (*this).Compute_coshlambda();
491
+
492
+    index_jalpha = 0;
493
+    for (int j = 0; j < chain.Nstrings; ++j) {
494
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
495
+	index_kbeta = 0;
496
+	for (int k = 0; k < chain.Nstrings; ++k) {
497
+	  for (int beta = 0; beta < base[k]; ++beta) {
498
+
499
+	    if ((j == k) && (alpha == beta)) {
500
+
501
+	      sum_hbar_XXZ = 0.0;
502
+
503
+	      for (int kp = 0; kp < chain.Nstrings; ++kp) {
504
+		for (int betap = 0; betap < base[kp]; ++betap) {
505
+		  if (!((j == kp) && (alpha == betap))) 
506
+		    sum_hbar_XXZ 
507
+		      += ddlambda_Theta_XXZ (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp], chain.par[j], chain.par[kp], 
508
+					     chain.si_n_anis_over_2);
509
+		}
510
+	      }
511
+
512
+	      Gaudin_Red[index_jalpha][index_kbeta] 
513
+		= 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);
514
+	    }
515
+
516
+	    else {
517
+	      if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
518
+		Gaudin_Red[index_jalpha][index_kbeta] = 
519
+		  complex<DP> ((chain.par[j] * chain.par[k] == 1) 
520
+			       ? chain.si_n_anis_over_2[4]/(pow(sinhlambda[j][alpha] * coshlambda[k][beta] 
521
+								 - coshlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq)
522
+			       : chain.si_n_anis_over_2[4]/(-pow(coshlambda[j][alpha] * coshlambda[k][beta] 
523
+								  - sinhlambda[j][alpha] * sinhlambda[k][beta], 2.0) + sinzetasq) );
524
+	      else 
525
+		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],
526
+											  chain.par[j], chain.par[k], chain.si_n_anis_over_2));
527
+	    }
528
+	    index_kbeta++;
529
+	  }
530
+	}
531
+	index_jalpha++;
532
+      }
533
+    }
534
+    return;
535
+  }
536
+
537
+  // ****************************************************************************************************
538
+
539
+  // non-member functions
540
+
541
+  inline DP fbar_XXZ (DP tanhlambda, int par, DP tannzetaover2)
542
+  {
543
+    DP result = 0.0;
544
+
545
+    if (par == 1) result = 2.0 * atan(tanhlambda/tannzetaover2);
546
+
547
+    else if (par == -1) result = -2.0 * atan(tanhlambda * tannzetaover2);
548
+
549
+    else JSCerror("Faulty parity in fbar_XXZ.");
550
+
551
+    return (result);
552
+  }
553
+
554
+  DP Theta_XXZ (DP tanhlambda, int nj, int nk, int parj, int park, DP* tannzetaover2)
555
+  {
556
+    DP result = 0.0;
557
+
558
+    if ((nj == 1) && (nk == 1)) result = fbar_XXZ(tanhlambda, parj*park, tannzetaover2[2]);
559
+    
560
+    else {
561
+
562
+      result = (nj == nk) ? 0.0 : fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk)]);
563
+
564
+      for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * fbar_XXZ(tanhlambda, parj*park, tannzetaover2[fabs(nj - nk) + 2*a]);
565
+
566
+      result += fbar_XXZ(tanhlambda, parj*park, tannzetaover2[nj + nk]);
567
+    }
568
+
569
+    return (result);
570
+  }
571
+
572
+  DP hbar_XXZ (DP lambda, int n, int par, DP* si_n_anis_over_2)
573
+  {
574
+    DP result = 0.0;
575
+
576
+    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));
577
+
578
+    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));
579
+
580
+    else JSCerror("Faulty parity in hbar_XXZ.");
581
+
582
+    return (result);
583
+  }
584
+								 
585
+  DP ddlambda_Theta_XXZ (DP lambda, int nj, int nk, int parj, int park, DP* si_n_anis_over_2)
586
+  {
587
+    DP result = (nj == nk) ? 0.0 : hbar_XXZ(lambda, fabs(nj - nk), parj*park, si_n_anis_over_2);
588
+
589
+    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);
590
+
591
+    result += hbar_XXZ(lambda, nj + nk, parj*park, si_n_anis_over_2);
592
+
593
+    return (result);
594
+  }
595
+
596
+
597
+  XXZ_Bethe_State Add_Particle_at_Center (const XXZ_Bethe_State& RefState)
598
+  {
599
+    if (2*RefState.base.Mdown == RefState.chain.Nsites) 
600
+      JSCerror("Trying to add a down spin to a zero-magnetized chain in Add_Particle_at_Center.");
601
+
602
+    Vect<int> newM = RefState.base.Nrap;
603
+    newM[0] = newM[0] + 1;
604
+
605
+    Heis_Base newBase (RefState.chain, newM);
606
+
607
+    XXZ_Bethe_State ReturnState (RefState.chain, newBase);
608
+
609
+    for (int il = 1; il < RefState.chain.Nstrings; ++il)
610
+      for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha) 
611
+	ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
612
+
613
+    // Add a quantum number in middle (explicitly: to right of index M[0]/2) 
614
+    // and shift quantum numbers by half-integer away from added one:
615
+    ReturnState.Ix2[0][RefState.base.Nrap[0]/2] = RefState.Ix2[0][RefState.base.Nrap[0]/2] - 1;
616
+    for (int i = 0; i < RefState.base.Nrap[0] + 1; ++i)
617
+      ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] = RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
618
+
619
+    return(ReturnState);
620
+  }
621
+
622
+
623
+  XXZ_Bethe_State Remove_Particle_at_Center (const XXZ_Bethe_State& RefState)
624
+  {
625
+    if (RefState.base.Nrap[0] == 0)
626
+      JSCerror("Trying to remove a down spin in an empty Nrap[0] state.");
627
+
628
+    Vect<int> newM = RefState.base.Nrap;
629
+    newM[0] = newM[0] - 1;
630
+
631
+    Heis_Base newBase (RefState.chain, newM);
632
+
633
+    XXZ_Bethe_State ReturnState (RefState.chain, newBase);
634
+
635
+    for (int il = 1; il < RefState.chain.Nstrings; ++il)
636
+      for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha) 
637
+	ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
638
+
639
+    // Remove midmost and shift quantum numbers by half-integer towards removed one:
640
+    for (int i = 0; i < RefState.base.Nrap[0]-1; ++i)
641
+      ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
642
+
643
+    return(ReturnState);
644
+    }
645
+  
646
+} // namespace JSC

+ 814
- 0
src/HEIS/XXZ_gpd_Bethe_State.cc View File

@@ -0,0 +1,814 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+File:  src/HEIS/XXZ_gpd_Bethe_State.cc
10
+
11
+Purpose:  Defines all functions for XXZ_gpd_Bethe_State
12
+
13
+******************************************************************/
14
+
15
+
16
+#include "JSC.h"
17
+
18
+using namespace std;
19
+
20
+namespace JSC {
21
+
22
+  // Function prototypes
23
+
24
+  inline DP fbar_XXZ_gpd (DP lambda, int par, DP tanhnetaover2);
25
+  DP Theta_XXZ_gpd (DP lambda, int nj, int nk, DP* tanhnetaover2);
26
+  DP hbar_XXZ_gpd (DP lambda, int n, DP* si_n_anis_over_2);
27
+  DP ddlambda_Theta_XXZ_gpd (DP lambda, int nj, int nk, DP* si_n_anis_over_2);
28
+
29
+
30
+  //***************************************************************************************************
31
+
32
+  // Function definitions:  class XXZ_gpd_Bethe_State
33
+
34
+  XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State () 
35
+    : Heis_Bethe_State(), sinlambda(Lambda(chain, 1)), coslambda(Lambda(chain, 1)), tanlambda(Lambda(chain, 1)) 
36
+  {};
37
+
38
+  XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const XXZ_gpd_Bethe_State& RefState) // copy constructor
39
+    : Heis_Bethe_State(RefState), 
40
+      sinlambda(Lambda(RefState.chain, RefState.base)), coslambda(Lambda(RefState.chain, RefState.base)), 
41
+      tanlambda(Lambda(RefState.chain, RefState.base)) 
42
+  {
43
+    // copy arrays into new ones
44
+
45
+    for (int j = 0; j < RefState.chain.Nstrings; ++j) {
46
+      for (int alpha = 0; alpha < RefState.base[j]; ++j) {
47
+	sinlambda[j][alpha] = RefState.sinlambda[j][alpha];
48
+	coslambda[j][alpha] = RefState.coslambda[j][alpha];
49
+	tanlambda[j][alpha] = RefState.tanlambda[j][alpha];
50
+      }
51
+    }
52
+  }
53
+  
54
+  XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, int M) 
55
+    : Heis_Bethe_State(RefChain, M), 
56
+      sinlambda(Lambda(RefChain, M)), coslambda(Lambda(RefChain, M)), tanlambda(Lambda(RefChain, M))
57
+  {
58
+    if (RefChain.Delta <= 1.0) JSCerror("Delta too low in XXZ_gpd_Bethe_State constructor");
59
+  }
60
+
61
+  XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, const Heis_Base& RefBase) 
62
+    : Heis_Bethe_State(RefChain, RefBase),
63
+      sinlambda(Lambda(RefChain, RefBase)), coslambda(Lambda(RefChain, RefBase)), 
64
+      tanlambda(Lambda(RefChain, RefBase)) 
65
+  {
66
+    if (RefChain.Delta <= 1.0) JSCerror("Delta too low in XXZ_gpd_Bethe_State constructor");
67
+  }
68
+  /*
69
+  XXZ_gpd_Bethe_State::XXZ_gpd_Bethe_State (const Heis_Chain& RefChain, long long int base_id_ref, long long int type_id_ref)
70
+    : Heis_Bethe_State(RefChain, base_id_ref, type_id_ref),
71
+      sinlambda(Lambda(chain, base)), coslambda(Lambda(chain, base)), tanlambda(Lambda(chain, base))
72
+  {
73
+    if (RefChain.Delta <= 1.0) JSCerror("Delta too low in XXZ_gpd_Bethe_State constructor");
74
+  }
75
+  */
76
+  XXZ_gpd_Bethe_State& XXZ_gpd_Bethe_State::operator= (const XXZ_gpd_Bethe_State& RefState)
77
+  {
78
+    if (this != &RefState) {
79
+      chain = RefState.chain;
80
+      base = RefState.base;
81
+      //offsets = RefState.offsets;
82
+      Ix2 = RefState.Ix2;
83
+      lambda = RefState.lambda;
84
+      BE = RefState.BE;
85
+      diffsq = RefState.diffsq;
86
+      conv = RefState.conv;
87
+      iter = RefState.iter;
88
+      iter_Newton = RefState.iter_Newton;
89
+      E = RefState.E;
90
+      iK = RefState.iK;
91
+      K = RefState.K;
92
+      lnnorm = RefState.lnnorm;
93
+      //base_id = RefState.base_id;
94
+      //type_id = RefState.type_id;
95
+      //id = RefState.id;
96
+      //maxid = RefState.maxid;
97
+      //nparticles = RefState.nparticles;
98
+      label = RefState.label;
99
+
100
+      sinlambda = RefState.sinlambda;
101
+      coslambda = RefState.coslambda;
102
+      tanlambda = RefState.tanlambda;
103
+    }
104
+    return(*this);
105
+  }
106
+
107
+
108
+  // Member functions
109
+
110
+  void XXZ_gpd_Bethe_State::Set_Free_lambdas()
111
+  {
112
+    // Sets all the rapidities to the solutions of the BAEs without scattering terms
113
+
114
+    for (int i = 0; i < chain.Nstrings; ++i) {
115
+
116
+      for (int alpha = 0; alpha < base[i]; ++alpha) {
117
+
118
+	lambda[i][alpha] = atan((tanh(chain.Str_L[i] * 0.5 * chain.anis) * tan(PI * 0.5 * Ix2[i][alpha]/chain.Nsites)));
119
+
120
+      }
121
+    }
122
+    
123
+    return;
124
+  }
125
+
126
+  void XXZ_gpd_Bethe_State::Compute_sinlambda()
127
+  {
128
+    for (int j = 0; j < chain.Nstrings; ++j) {
129
+
130
+      for (int alpha = 0; alpha < base[j]; ++alpha) sinlambda[j][alpha] = sin(lambda[j][alpha]);
131
+    }
132
+    return;
133
+  }
134
+
135
+  void XXZ_gpd_Bethe_State::Compute_coslambda()
136
+  {
137
+    for (int j = 0; j < chain.Nstrings; ++j) {
138
+
139
+      for (int alpha = 0; alpha < base[j]; ++alpha) coslambda[j][alpha] = cos(lambda[j][alpha]);
140
+    }
141
+    return;
142
+  }
143
+
144
+  void XXZ_gpd_Bethe_State::Compute_tanlambda()
145
+  {
146
+    for (int j = 0; j < chain.Nstrings; ++j) {
147
+
148
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
149
+	tanlambda[j][alpha] = tan(lambda[j][alpha]);
150
+	//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;
151
+      }
152
+    }
153
+    return;
154
+  }
155
+
156
+  bool XXZ_gpd_Bethe_State::Check_Admissibility(char option)
157
+  {
158
+    // This function checks the admissibility of the Ix2's of a state:  
159
+    // returns false if there are higher strings with Ix2 = 0, a totally symmetric distribution of I's at each level,
160
+    // and strings of equal length modulo 2 and parity with Ix2 = 0, meaning at least two equal roots in BAE.
161
+
162
+    bool answer = true;
163
+    Vect<bool> Zero_at_level(false, chain.Nstrings); // whether there exists an Ix2 == 0 at a given level
164
+
165
+    /*
166
+    Vect<bool> min_Ix2_max_busy(false, chain.Nstrings); 
167
+    Vect<bool> plus_Ix2_max_busy(false, chain.Nstrings);
168
+    for (int j = 0; j < chain.Nstrings; ++j) 
169
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
170
+	if (Ix2[j][alpha] == -base.Ix2_max[j]) min_Ix2_max_busy[j] = true;
171
+	if (Ix2[j][alpha] == base.Ix2_max[j]) plus_Ix2_max_busy[j] = true;
172
+      }
173
+    */
174
+    /*
175
+    // State is not admissible if this is false:  -N/2 + 1 \leq \sum I^j_{\alpha} \leq N 
176
+    int sum_all_Ix2 = 0;
177
+    for (int j = 0; j < chain.Nstrings; ++j) 
178
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
179
+	sum_all_Ix2 += Ix2[j][alpha];
180
+      }
181
+    if (sum_all_Ix2 > chain.Nsites || sum_all_Ix2 <= -chain.Nsites) {
182
+      cout << "\tSum Ix2 out of fundamental interval: sum_all_Ix2 = " << sum_all_Ix2 << "\tfor N = " << chain.Nsites << endl;
183
+      return(false);
184
+    }
185
+    */
186
+    //Deactivated 2014 06 11, put in Heis_Form_Factor_Entry.cc
187
+    /*
188
+    // 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:
189
+    int sum1 = 0;
190
+    for (int j = 0; j < chain.Nstrings; ++j) {
191
+      sum1 = 0;
192
+      for (int k = 0; k < chain.Nstrings; ++k) {
193
+	sum1 += base[k] * (2 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1 : 0));
194
+      }
195
+      // Define limits...
196
+      //if (!((Nrap[j] + Ix2_max[j]) % 2)) Ix2_max[j] -= 1;
197
+
198
+      // This almost does it:  only missing are the states with one on -PI/2 and one on PI/2
199
+      if (base[j] >= 1 && (Ix2[j][0] <= -(chain.Nsites - sum1) || 
200
+			   (Ix2[j][base[j] - 1] - Ix2[j][0]) > 2*(chain.Nsites - sum1))) {
201
+	//cout << "\tAn Ix2 is out of interval at level " << j << endl;
202
+	//cout << Ix2[j][base[j] - 1] << "\t" << Ix2[j][0] << "\t" << chain.Nsites << "\t" << sum1 << endl;
203
+	return(false);
204
+      }
205
+    }
206
+    */
207
+
208
+    /*
209
+    // State is not admissible if both a min_ and plus_Ix2_max are busy simultaneously:
210
+    bool is_a_min_Ix2_max_busy = false;
211
+    for (int j = 0; j < chain.Nstrings; ++j) if (min_Ix2_max_busy[j]) is_a_min_Ix2_max_busy = true;
212
+    bool is_a_plus_Ix2_max_busy = false;
213
+    for (int j = 0; j < chain.Nstrings; ++j) if (plus_Ix2_max_busy[j]) is_a_plus_Ix2_max_busy = true;
214
+    */
215
+    /*
216
+    // State is not admissible if all min_Ix2_max are busy simultaneously:
217
+    bool any_min_Ix2_max_free = false;
218
+    for (int j = 0; j < chain.Nstrings; ++j) 
219
+      if (base[j] > 0 && !min_Ix2_max_busy[j]) any_min_Ix2_max_free = true;
220
+    if (!any_min_Ix2_max_free) return(false);
221
+    */
222
+    /*
223
+    // State is not admissible if -Ix2_max, -Ix2_max + 2, ..., -Ix2_max + 2*(Str_L - 1) are busy:
224
+    for (int j = 0; j < chain.Nstrings; ++j) 
225
+      if (base[j] > 0 && Ix2[j][0] <= -base.Ix2_max[j] + 2*(chain.Str_L[j] - 1)) 
226
+	return(false);
227
+    // Almost correct with above !  
228
+    // State is not admissible if Ix2_max - 2, ..., Ix2_max - 2*(Str_L - 2) are busy (NB:  one slot more than on left):
229
+    for (int j = 0; j < chain.Nstrings; ++j) 
230
+      if (base[j] > 0 && Ix2[j][base[j] - 1] >= base.Ix2_max[j] - 2*(chain.Str_L[j] - 2)) 
231
+	return(false);
232
+    */
233
+
234
+    // Check that at all at least doubly occupied levels, the difference between max and min quantum numbers
235
+    // is strictly smaller than 2*Ix2_max - 2, so that lambda_max - lambda_min < PI at each level:
236
+    //for (int j = 0; j < chain.Nstrings; ++j)
237
+    //if (base[j] >= 2 && Ix2[j][base[j] - 1] - Ix2[j][0] >= 2* base.Ix2_max[j] - 2) answer = false;
238
+
239
+    //if (is_a_min_Ix2_max_busy && is_a_plus_Ix2_max_busy) return(false);
240
+
241
+    bool higher_string_on_zero = false;
242
+
243
+    for (int j = 0; j < chain.Nstrings; ++j) {
244
+      // The following line puts answer to true if there is at least one higher string with zero Ix2
245
+      for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] == 0) && (chain.Str_L[j] > 2) /*&& !(chain.Str_L[j] % 2)*/) 
246
+	higher_string_on_zero = true;  
247
+      for (int alpha = 0; alpha < base[j]; ++alpha) if (Ix2[j][alpha] == 0) Zero_at_level[j] = true;         
248
+      // NOTE:  if base[j] == 0, Zero_at_level[j] remains false.
249
+    }
250
+
251
+    bool symmetric_state = (*this).Check_Symmetry();
252
+
253
+    bool string_coincidence = false;
254
+    // Checks that we have strings of equal length modulo 2 and same parity with Ix2 == 0, so equal rapidities, and inadmissibility
255
+    for (int j1 = 0; j1 < chain.Nstrings; ++j1) {
256
+      for (int j2 = j1 + 1; j2 < chain.Nstrings; ++j2)
257
+	if (Zero_at_level[j1] && Zero_at_level[j2] && (!((chain.Str_L[j1] + chain.Str_L[j2])%2))) 
258
+	  string_coincidence = true;
259
+    }
260
+
261
+    //bool onep_onem_on_zero = false;
262
+    //if (option == 'm' || option == 'p') { // for Smin, we also exclude symmetric states with 1+ and 1- strings on zero
263
+    //if (Zero_at_level[0] && Zero_at_level[1]) onep_onem_on_zero = true;
264
+    //}
265
+
266
+    //cout << min_Ix2_max_busy << "\t" << symmetric_state  << "\t" << higher_string_on_zero << "\t" << string_coincidence << "\t" << onep_onem_on_zero << endl;
267
+
268
+    //answer = !((symmetric_state && (higher_string_on_zero || string_coincidence || onep_onem_on_zero)));
269
+    answer = !(symmetric_state && (higher_string_on_zero || string_coincidence));
270
+
271
+    // Explicitly exclude state with min_Ix2_max_busy && iK == 0
272
+    //Compute_Momentum();
273
+    //answer = !((min_Ix2_max_busy && iK == 0) || (symmetric_state && (higher_string_on_zero || string_coincidence || onep_onem_on_zero)));
274
+
275
+    // Now check that no Ix2 is equal to +N (since we take -N into account, and I + N == I by periodicity of exp)
276
+
277
+    for (int j = 0; j < chain.Nstrings; ++j) 
278
+      for (int alpha = 0; alpha < base[j]; ++alpha) if ((Ix2[j][alpha] < -chain.Nsites) || (Ix2[j][alpha] >= chain.Nsites)) answer = false;    
279
+
280
+    if (!answer) {
281
+      E = 0.0;
282
+      K = 0.0;
283
+      conv = 0;
284
+      iter = 0;
285
+      iter_Newton = 0;
286
+      lnnorm = -100.0;
287
+    }
288
+
289
+    return(answer);  // answer == true:  nothing wrong with this Ix2_config
290
+  }
291
+
292
+  void XXZ_gpd_Bethe_State::Compute_BE (int j, int alpha)
293
+  {
294
+    // Fills in the BE members with the value of the Bethe equations.
295
+
296
+    tanlambda[j][alpha] = tan(lambda[j][alpha]);
297
+
298
+    DP sumtheta = 0.0;
299
+    
300
+    sumtheta = 0.0;
301
+    for (int k = 0; k < chain.Nstrings; ++k) {
302
+      for (int beta = 0; beta < base[k]; ++beta) 
303
+	if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) {
304
+	  sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta]) 
305
+									* chain.ta_n_anis_over_2[2])) 
306
+	    + PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI); 
307
+	}		
308
+	else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]), 
309
+					     chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
310
+	  + PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0)) 
311
+	  * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
312
+    }
313
+    sumtheta *= 2.0;
314
+    
315
+    BE[j][alpha] = 2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) 
316
+			  + PI * floor(0.5 + lambda[j][alpha]/PI))
317
+      - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
318
+  }        
319
+
320
+  void XXZ_gpd_Bethe_State::Compute_BE ()
321
+  {
322
+    // Fills in the BE members with the value of the Bethe equations.
323
+
324
+    (*this).Compute_tanlambda();
325
+
326
+    DP sumtheta = 0.0;
327
+    
328
+    for (int j = 0; j < chain.Nstrings; ++j) 
329
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
330
+	
331
+	sumtheta = 0.0;
332
+	for (int k = 0; k < chain.Nstrings; ++k) {
333
+	  for (int beta = 0; beta < base[k]; ++beta) 
334
+	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) {
335
+	      sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta]) 
336
+									    * chain.ta_n_anis_over_2[2])) 
337
+		+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI); 
338
+	    }		
339
+	    else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]), 
340
+						 chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
341
+	      + PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0)) 
342
+	      * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
343
+	}
344
+	sumtheta *= 2.0;
345
+	
346
+	BE[j][alpha] = 2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) 
347
+			      + PI * floor(0.5 + lambda[j][alpha]/PI))
348
+	  - (sumtheta + PI*Ix2[j][alpha])/chain.Nsites;
349
+      }        
350
+  }
351
+
352
+  DP XXZ_gpd_Bethe_State::Iterate_BAE (int j, int alpha)
353
+  {
354
+    // Returns a new iteration value for lambda[j][alpha] given tanlambda[][] and BE[][]
355
+    // Assumes that tanlambda[][] and BE[][] have been computed.
356
+
357
+    DP arg0 = 0.5 * (2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) 
358
+			    + PI * floor(0.5 + lambda[j][alpha]/PI)) - BE[j][alpha]);
359
+    DP arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan(
360
+							  arg0
361
+							  //0.5 * 
362
+							  //(PI * Ix2[j][alpha] + sumtheta)/chain.Nsites
363
+							  //(2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) 
364
+							  //  + PI * floor(0.5 + lambda[j][alpha]/PI)) - BE[j][alpha])
365
+							  );
366
+
367
+    return(atan(arg) 
368
+	   //+ PI * floor(0.5 + arg0)
369
+				  //0.5 * (Ix2[j][alpha] + sumtheta/PI)/(chain.Nsites)
370
+	   + PI * floor(0.5 + arg0/PI)
371
+				  );
372
+
373
+  }
374
+  /*
375
+  void XXZ_gpd_Bethe_State::Iterate_BAE ()
376
+  {
377
+    // Recalculates the rapidities by iterating Bethe equations
378
+
379
+    Lambda New_lambda(chain, base);
380
+    DP sumtheta = 0.0;
381
+    DP arg = 0.0;
382
+
383
+    // First, compute the tan of rapidities:
384
+    (*this).Compute_tanlambda();
385
+
386
+    for (int j = 0; j < chain.Nstrings; ++j) {
387
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
388
+
389
+	sumtheta = 0.0;
390
+	for (int k = 0; k < chain.Nstrings; ++k) {
391
+	  for (int beta = 0; beta < base[k]; ++beta) 
392
+	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
393
+	      sumtheta += atan((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta]) 
394
+									   * chain.ta_n_anis_over_2[2]))
395
+		+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI); 
396
+
397
+	    else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]), 
398
+					     chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
399
+	      + PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0)) 
400
+	      * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
401
+	}
402
+	sumtheta *= 2.0;
403
+
404
+	arg = chain.ta_n_anis_over_2[chain.Str_L[j]] * tan((PI * 0.5 * Ix2[j][alpha] + 0.5 * sumtheta)/chain.Nsites);
405
+
406
+	New_lambda[j][alpha] = atan(arg) + PI * floor(0.5 + (0.5 * Ix2[j][alpha] + 0.5 * sumtheta/PI)/(chain.Nsites));
407
+
408
+      }
409
+    }
410
+
411
+    DP New_diffsq = 0.0;
412
+
413
+    for (int j = 0; j < chain.Nstrings; ++j) {
414
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
415
+	//New_diffsq += pow(tan(New_lambda[j][alpha]) - tanlambda[j][alpha], 2.0);
416
+	New_diffsq += pow(New_lambda[j][alpha] - lambda[j][alpha], 2.0);
417
+	lambda[j][alpha] = 1.0 * New_lambda[j][alpha] + 0.0 * lambda[j][alpha];
418
+      }
419
+    }
420
+
421
+    diffsq = New_diffsq;
422
+    iter++;
423
+
424
+    return;
425
+  }
426
+  */
427
+  /*
428
+  void XXZ_gpd_Bethe_State::Iterate_BAE_Newton ()
429
+  {
430
+    // does one step of a Newton method on the rapidities...
431
+
432
+    Vect_DP RHSBAE (0.0, base.Nraptot);  // contains RHS of BAEs
433
+    Vect_CX dlambda (0.0, base.Nraptot);  // contains delta lambda computed from Newton's method
434
+    SQMat_CX Gaudin (0.0, base.Nraptot);
435
+    Vect_INT indx (base.Nraptot);
436
+    DP sumtheta = 0.0;
437
+    DP arg = 0.0;
438
+    DP fn_arg = 0.0;
439
+    DP olddiffsq = diffsq;
440
+
441
+    // Compute the RHS of the BAEs:
442
+
443
+    int index = 0;
444
+
445
+    (*this).Compute_tanlambda();
446
+
447
+    for (int j = 0; j < chain.Nstrings; ++j) {
448
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
449
+
450
+	sumtheta = 0.0;
451
+	for (int k = 0; k < chain.Nstrings; ++k) {
452
+	  for (int beta = 0; beta < base[k]; ++beta) 
453
+	    if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) {
454
+	      sumtheta += atan ((tanlambda[j][alpha] - tanlambda[k][beta])/((1.0 + tanlambda[j][alpha] * tanlambda[k][beta]) 
455
+									    * chain.ta_n_anis_over_2[2])) 
456
+		+ PI * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI); 
457
+	    }		
458
+	    else sumtheta += 0.5 * Theta_XXZ_gpd((tanlambda[j][alpha] - tanlambda[k][beta])/(1.0 + tanlambda[j][alpha] * tanlambda[k][beta]), 
459
+					     chain.Str_L[j], chain.Str_L[k], chain.ta_n_anis_over_2)
460
+	      + PI * (2.0 * JSC::min(chain.Str_L[j], chain.Str_L[k]) - ((j == k) ? 1.0 : 0)) 
461
+	      * floor(0.5 + (lambda[j][alpha] - lambda[k][beta])/PI);
462
+	}
463
+	sumtheta *= 2.0;
464
+
465
+	RHSBAE[index] = chain.Nsites * 2.0 * (atan(tanlambda[j][alpha]/chain.ta_n_anis_over_2[chain.Str_L[j]]) 
466
+       					      + PI * floor(0.5 + lambda[j][alpha]/PI))
467
+					      //					      )
468
+	  - sumtheta - PI*Ix2[j][alpha];
469
+	index++;
470
+      }
471
+    }
472
+    
473
+    (*this).Build_Reduced_Gaudin_Matrix (Gaudin);
474
+
475
+    for (int i = 0; i < base.Nraptot; ++i) dlambda[i] = - RHSBAE[i];
476
+
477
+    DP d;
478
+    ludcmp_CX (Gaudin, indx, d);
479
+    lubksb_CX (Gaudin, indx, dlambda);
480
+
481
+    diffsq = 0.0;
482
+    //    for (int i = 0; i < base.Nraptot; ++i) diffsq += norm(dlambda[i]);
483
+    int ctr = 0;
484
+    for (int j = 0; j < chain.Nstrings; ++j) {
485
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
486
+	diffsq += norm(tan(lambda[j][alpha] + dlambda[ctr]) - tanlambda[j][alpha]);
487
+	//	cout << "lambda = " << lambda[j][alpha] << "\tdlambda = " << dlambda[ctr] << endl;
488
+	ctr++;
489
+      }
490
+    }
491
+
492
+    // if we've converged, calculate the norm here, since the work has been done...
493
+
494
+    if (diffsq < chain.prec) {
495
+      lnnorm = 0.0;
496
+      for (int j = 0; j < base.Nraptot; j++) lnnorm += log(abs(Gaudin[j][j]));
497
+    }
498
+
499
+    index = 0;
500
+    for (int j = 0; j < chain.Nstrings; ++j) {
501
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
502
+	lambda[j][alpha] += real(dlambda[index]);
503
+	index++;
504
+      }
505
+    }
506
+
507
+    iter_Newton++;
508
+
509
+    //    cout << "iter_N = " << iter_Newton << "\t" << diffsq << endl;
510
+
511
+    return;
512
+  }
513
+  */
514
+  bool XXZ_gpd_Bethe_State::Check_Rapidities()
515
+  {
516
+    bool nonan = true;
517
+
518
+    for (int j = 0; j < chain.Nstrings; ++j)
519
+      for (int alpha = 0; alpha < base[j]; ++alpha) if (nonan) nonan = ((!is_nan(lambda[j][alpha])) 
520
+									//&& (lambda[j][alpha] > -0.5*PI*chain.Str_L[j]) 
521
+									//&& (lambda[j][alpha] <= 0.5*PI*chain.Str_L[j])
522
+									);
523
+
524
+    bool all_within_pi_interval = true;
525
+    DP min_lambda = 10.0;
526
+    DP max_lambda = -10.0;
527
+    for (int j = 0; j < chain.Nstrings; ++j)
528
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
529
+	if (lambda[j][alpha] < min_lambda) min_lambda = lambda[j][alpha];
530
+	if (lambda[j][alpha] > max_lambda) max_lambda = lambda[j][alpha];
531
+      }
532
+
533
+    //all_within_pi_interval = (fabs(max_lambda - min_lambda) < PI - 0.0 * 1.0e-12);
534
+    // Use pi interval, but centered on 0:
535
+    all_within_pi_interval = max_lambda < 0.5* PI + 1.0e-8 && min_lambda > -0.5* PI - 1.0e-8;
536
+    //nonan *= all_within_pi_interval;
537
+
538
+    return nonan;
539
+  }
540
+
541
+  DP XXZ_gpd_Bethe_State::String_delta ()
542
+  {
543
+    // Computes the sum of absolute value of \delta^{a, a+1} in string hypothesis, for a given bethe eigenstate
544
+
545
+    DP delta = 0.0;
546
+
547
+    int occupied_strings = 0;
548
+    for (int i = 0; i < (*this).chain.Nstrings; ++i) if ((*this).chain.Str_L[i] > 1) occupied_strings += (*this).base.Nrap[i];
549
+
550
+    //if ((*this).conv == 0) delta = 1.0;
551
+
552
+    if (occupied_strings == 0) delta = 0.0;
553
+
554
+    else {
555
+
556
+      Vect_DP ln_deltadiff(0.0, 1000);  // contains ln |delta^{a, a+1}|
557
+      Vect_DP deltadiff(0.0, 1000);  // contains |delta^{a, a+1}|
558
+
559
+      complex<DP> log_BAE_reg = 0.0;
560
+      
561
+      for (int j = 0; j < (*this).chain.Nstrings; ++j) {
562
+	for (int alpha = 0; alpha < (*this).base[j]; ++alpha) {
563
+
564
+	  ln_deltadiff = 0.0;
565
+	      
566
+	  for (int a = 1; a <= (*this).chain.Str_L[j]; ++a) {
567
+	    
568
+	    if ((*this).chain.Str_L[j] > 1) {  // else the BAE are already 1
569
+
570
+	      log_BAE_reg = DP((*this).chain.Nsites) * log(sin((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis 
571
+							     * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a + 1.0))
572
+			    /sin((*this).lambda[j][alpha] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[j] + 1.0 - 2.0 * a - 1.0)));
573
+	      
574
+	      for (int k = 0; k < (*this).chain.Nstrings; ++k) 
575
+		for (int beta = 0; beta < (*this).base[k]; ++beta) 
576
+		  for (int b = 1; b <= (*this).chain.Str_L[k]; ++b) {
577
+		    if ((j != k) || (alpha != beta) || (a != b - 1)) 
578
+
579
+		      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 )) 
580
+				      - ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )) 
581
+					     - II * (*this).chain.anis));
582
+		    
583
+		    if ((j != k) || (alpha != beta) || (a != b + 1)) 
584
+
585
+		      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 ))
586
+				      - ((*this).lambda[k][beta] + 0.5 * II * (*this).chain.anis * ((*this).chain.Str_L[k] + 1.0 - 2.0 * b )) 
587
+					     + II * (*this).chain.anis));
588
+		  }
589
+
590
+	      // The regular LHS of BAE is now defined.  Now sum up the deltas...
591
+	      
592
+	      if (a == 1) ln_deltadiff[0] = -real(log_BAE_reg);
593
+	      
594
+	      else if (a < (*this).chain.Str_L[j]) ln_deltadiff[a - 1] = ln_deltadiff[a-2] - real(log_BAE_reg);
595
+	      
596
+	      else if (a == (*this).chain.Str_L[j]) ln_deltadiff[a-1] = real(log_BAE_reg);
597
+
598
+	    } // if ((*this).chain.Str_L[j] > 1)
599
+	    
600
+	  } // for (int a = 1; ...
601
+
602
+	  for (int a = 0; a < (*this).chain.Str_L[j]; ++a) {
603
+	    deltadiff[a] = ln_deltadiff[a] != 0.0 ? exp(ln_deltadiff[a]) : 0.0;
604
+	    delta += fabs(deltadiff[a]);
605
+	  }  
606
+	      
607
+	} // alpha sum
608
+      } // j sum
609
+
610
+      if (is_nan(delta)) delta = 1.0; // sentinel
611
+
612
+    } // else
613
+
614
+    return delta;
615
+  }
616
+
617
+
618
+  void XXZ_gpd_Bethe_State::Compute_Energy ()
619
+  {
620
+    DP sum = 0.0;
621
+    
622
+    for (int j = 0; j < chain.Nstrings; ++j) {
623
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
624
+	sum += sinh(chain.Str_L[j] * chain.anis) / (cos(2.0 * lambda[j][alpha]) - cosh(chain.Str_L[j] * chain.anis));
625
+      }
626
+    }
627
+
628
+    sum *= chain.J * sinh(chain.anis);
629
+    
630
+    E = sum;
631
+
632
+    return;
633
+  }
634
+
635
+  /*
636
+  void XXZ_gpd_Bethe_State::Compute_Momentum ()
637
+  {
638
+    int sum_Ix2 = 0;
639
+    DP sum_M = 0.0;
640
+
641
+    for (int j = 0; j < chain.Nstrings; ++j) {
642
+      sum_M += base[j];
643
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
644
+	sum_Ix2 += Ix2[j][alpha];
645
+      }
646
+    }
647
+
648
+    iK = (chain.Nsites/2) * int(sum_M) - (sum_Ix2/2);
649
+
650
+    while (iK >= chain.Nsites) iK -= chain.Nsites;
651
+    while (iK < 0) iK += chain.Nsites;
652
+
653
+    K = PI * sum_M - PI * sum_Ix2/chain.Nsites;
654
+
655
+    while (K >= 2.0*PI) K -= 2.0*PI;
656
+    while (K < 0.0) K += 2.0*PI;
657
+
658
+    return;
659
+  }
660
+  */
661
+
662
+  void XXZ_gpd_Bethe_State::Build_Reduced_Gaudin_Matrix (SQMat<complex<DP> >& Gaudin_Red)
663
+  {
664
+
665
+    if (Gaudin_Red.size() != base.Nraptot) JSCerror("Passing matrix of wrong size in Build_Reduced_Gaudin_Matrix.");
666
+
667
+    int index_jalpha;
668
+    int index_kbeta;
669
+
670
+    DP sum_hbar_XXZ = 0.0;
671
+
672
+    DP sinhetasq = pow(sinh(chain.anis), 2.0);
673
+
674
+    (*this).Compute_sinlambda();
675
+    (*this).Compute_coslambda();
676
+
677
+    index_jalpha = 0;
678
+    for (int j = 0; j < chain.Nstrings; ++j) {
679
+      for (int alpha = 0; alpha < base[j]; ++alpha) {
680
+	index_kbeta = 0;
681
+	for (int k = 0; k < chain.Nstrings; ++k) {
682
+	  for (int beta = 0; beta < base[k]; ++beta) {
683
+
684
+	    if ((j == k) && (alpha == beta)) {
685
+
686
+	      sum_hbar_XXZ = 0.0;
687
+
688
+	      for (int kp = 0; kp < chain.Nstrings; ++kp) {
689
+		for (int betap = 0; betap < base[kp]; ++betap) {
690
+		  if (!((j == kp) && (alpha == betap))) 
691
+		    sum_hbar_XXZ 
692
+		      += ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[kp][betap], chain.Str_L[j], chain.Str_L[kp],  
693
+					     chain.si_n_anis_over_2);
694
+		}
695
+	      }
696
+
697
+	      Gaudin_Red[index_jalpha][index_kbeta] 
698
+		= complex<DP> ( chain.Nsites * hbar_XXZ_gpd (lambda[j][alpha], chain.Str_L[j], chain.si_n_anis_over_2) - sum_hbar_XXZ);
699
+	    }
700
+	    
701
+	    else {
702
+	      if ((chain.Str_L[j] == 1) && (chain.Str_L[k] == 1)) 
703
+		Gaudin_Red[index_jalpha][index_kbeta] = 
704
+		  complex<DP> (chain.si_n_anis_over_2[4]/(pow(sinlambda[j][alpha] * coslambda[k][beta] 
705
+							       - coslambda[j][alpha] * sinlambda[k][beta], 2.0) + sinhetasq));
706
+	      else 
707
+		Gaudin_Red[index_jalpha][index_kbeta] = complex<DP> (ddlambda_Theta_XXZ_gpd (lambda[j][alpha] - lambda[k][beta], chain.Str_L[j], 
708
+											     chain.Str_L[k], chain.si_n_anis_over_2));
709
+	    }
710
+	    index_kbeta++;
711
+	  }
712
+	}
713
+	index_jalpha++;
714
+      }
715
+    }
716
+
717
+    return;
718
+  }
719
+
720
+
721
+  // ****************************************************************************************************
722
+
723
+  // non-member functions
724
+
725
+  inline DP fbar_XXZ_gpd (DP tanlambda, DP tanhnetaover2)
726
+  {
727
+    return (2.0 * atan(tanlambda/tanhnetaover2));
728
+  }
729
+
730
+  DP Theta_XXZ_gpd (DP tanlambda, int nj, int nk, DP* tanhnetaover2)
731
+  {
732
+    DP result;
733
+
734
+    if ((nj == 1) && (nk == 1)) result = fbar_XXZ_gpd(tanlambda, tanhnetaover2[2]);
735
+    
736
+    else {
737
+
738
+      result = (nj == nk) ? 0.0 : fbar_XXZ_gpd(tanlambda, tanhnetaover2[fabs(nj - nk)]);
739
+
740
+      for (int a = 1; a < JSC::min(nj, nk); ++a) result += 2.0 * fbar_XXZ_gpd(tanlambda, tanhnetaover2[fabs(nj - nk) + 2*a]);
741
+
742
+      result += fbar_XXZ_gpd(tanlambda, tanhnetaover2[nj + nk]);
743
+    }
744
+
745
+    return (result);
746
+  }
747
+
748
+  DP hbar_XXZ_gpd (DP lambda, int n, DP* si_n_anis_over_2)
749
+  {
750
+    return (si_n_anis_over_2[2*n]/(pow(sin(lambda), 2.0) + pow(si_n_anis_over_2[n], 2.0)));
751
+  }
752
+								 
753
+  DP ddlambda_Theta_XXZ_gpd (DP lambda, int nj, int nk, DP* si_n_anis_over_2)
754
+  {
755
+    DP result = (nj == nk) ? 0.0 : hbar_XXZ_gpd(lambda, fabs(nj - nk), si_n_anis_over_2);
756
+
757
+    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);
758
+
759
+    result += hbar_XXZ_gpd(lambda, nj + nk, si_n_anis_over_2);
760
+
761
+    return (result);
762
+  }
763
+
764
+
765
+  XXZ_gpd_Bethe_State Add_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState)
766
+  {
767
+    if (2*RefState.base.Mdown == RefState.chain.Nsites) 
768
+      JSCerror("Trying to add a down spin to a zero-magnetized chain in Add_Particle_at_Center.");
769
+
770
+    Vect<int> newM = RefState.base.Nrap;
771
+    newM[0] = newM[0] + 1;
772
+
773
+    Heis_Base newBase (RefState.chain, newM);
774
+
775
+    XXZ_gpd_Bethe_State ReturnState (RefState.chain, newBase);
776
+
777
+    for (int il = 1; il < RefState.chain.Nstrings; ++il)
778
+      for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha) 
779
+	ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
780
+
781
+    // Add a quantum number in middle (explicitly: to right of index M[0]/2) 
782
+    // and shift quantum numbers by half-integer away from added one:
783
+    ReturnState.Ix2[0][RefState.base.Nrap[0]/2] = RefState.Ix2[0][RefState.base.Nrap[0]/2] - 1;
784
+    for (int i = 0; i < RefState.base.Nrap[0] + 1; ++i)
785
+      ReturnState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] = RefState.Ix2[0][i] - 1 + 2*(i >= RefState.base.Nrap[0]/2);
786
+
787
+    return(ReturnState);
788
+  }
789
+
790
+
791
+  XXZ_gpd_Bethe_State Remove_Particle_at_Center (const XXZ_gpd_Bethe_State& RefState)
792
+  {
793
+    if (RefState.base.Nrap[0] == 0)
794
+      JSCerror("Trying to remove a down spin in an empty Nrap[0] state.");
795
+
796
+    Vect<int> newM = RefState.base.Nrap;
797
+    newM[0] = newM[0] - 1;
798
+
799
+    Heis_Base newBase (RefState.chain, newM);
800
+
801
+    XXZ_gpd_Bethe_State ReturnState (RefState.chain, newBase);
802
+
803
+    for (int il = 1; il < RefState.chain.Nstrings; ++il)
804
+      for (int alpha = 0; alpha < RefState.base.Nrap[il]; ++alpha) 
805
+	ReturnState.Ix2[il][alpha] = RefState.Ix2[il][alpha];
806
+
807
+    // Remove midmost and shift quantum numbers by half-integer towards removed one:
808
+    for (int i = 0; i < RefState.base.Nrap[0]-1; ++i)
809
+      ReturnState.Ix2[0][i] = RefState.Ix2[0][i + (i >= RefState.base.Nrap[0]/2)] + 1 - 2*(i >= RefState.base.Nrap[0]/2);
810
+
811
+    return(ReturnState);
812
+    }
813
+  
814
+} // namespace JSC

+ 253
- 0
src/HEIS/ln_Overlap_XXX.cc View File

@@ -0,0 +1,253 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+***********************************************************/
10
+
11
+#include "JSC.h"
12
+
13
+using namespace JSC;
14
+
15
+namespace JSC {
16
+
17
+inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
18
+{
19
+  complex<DP> ans = 0.0;
20
+
21
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
22
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
23
+      for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
24
+
25
+	if (!((j == k) && (alpha == beta) && (a == b))) 
26
+	  ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
27
+		     + 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))); 
28
+      }
29
+    }
30
+  }
31
+
32
+  return(ans);
33
+}
34
+
35
+inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
36
+{
37
+  complex<DP> ans = 0.0;
38
+
39
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
40
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
41
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
42
+
43
+	ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
44
+		   + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
45
+      }
46
+    }
47
+  }
48
+
49
+  return(ans);
50
+}
51
+
52
+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)
53
+{
54
+  return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
55
+	       + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
56
+	      * (A.lambda[j][alpha] - B.lambda[k][beta]
57
+		 + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
58
+}
59
+
60
+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)
61
+{
62
+  return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
63
+		      + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5)) 
64
+		      )) 
65
+	  * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
66
+}
67
+
68
+complex<DP> ln_Overlap (XXX_Bethe_State& A, XXX_Bethe_State& B)
69
+{
70
+  // This function returns the overlap of states A and B.
71
+  // The A and B states can contain strings.
72
+
73
+  // IMPORTANT ASSUMPTIONS:
74
+  // - State B is an eigenstate of the model on which the overlap measure is defined  
75
+
76
+  // Check that A and B are compatible:  same Mdown
77
+
78
+  if (A.base.Mdown != B.base.Mdown) return(complex<DP>(-300.0));  // overlap vanishes
79
+
80
+  // Some convenient arrays
81
+
82
+  Lambda re_ln_Fn_F_B_0(B.chain, B.base);
83
+  Lambda im_ln_Fn_F_B_0(B.chain, B.base);
84
+  Lambda re_ln_Fn_G_0(B.chain, B.base);
85
+  Lambda im_ln_Fn_G_0(B.chain, B.base);
86
+  Lambda re_ln_Fn_G_2(B.chain, B.base);
87
+  Lambda im_ln_Fn_G_2(B.chain, B.base);
88
+
89
+  //complex<DP> ln_prod1 = 0.0;
90
+  //complex<DP> ln_prod2 = 0.0;
91
+  complex<DP> ln_prod3 = 0.0;
92
+  complex<DP> ln_prod4 = 0.0;
93
+
94
+  /*
95
+  for (int i = 0; i < A.chain.Nstrings; ++i) 
96
+    for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
97
+      for (int a = 1; a <= A.chain.Str_L[i]; ++a)
98
+	ln_prod1 += log(norm((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
99
+
100
+  for (int i = 0; i < B.chain.Nstrings; ++i) 
101
+    for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
102
+      for (int a = 1; a <= B.chain.Str_L[i]; ++a)
103
+	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)
104
+	  ln_prod2 += log(norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
105
+  */
106
+
107
+  // Define the F ones earlier...
108
+
109
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
110
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
111
+      re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
112
+      im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
113
+      re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
114
+      im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
115
+      re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
116
+      im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
117
+    }
118
+  }
119
+
120
+  // Define regularized products in prefactors
121
+
122
+  for (int j = 0; j < A.chain.Nstrings; ++j)
123
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
124
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) 
125
+	ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);  
126
+
127
+  //  ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
128
+
129
+  for (int k = 0; k < B.chain.Nstrings; ++k)
130
+    for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
131
+      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
132
+	if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
133
+	else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
134
+    }
135
+  
136
+  //  ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
137
+
138
+  // Now proceed to build the Hm2P matrix
139
+
140
+  SQMat_CX Hm2P(0.0, A.base.Mdown);
141
+
142
+  int index_a = 0;
143
+  int index_b = 0;
144
+
145
+  complex<DP> sum1 = 0.0;
146
+  //complex<DP> sum2 = 0.0;
147
+  complex<DP> prod_num = 0.0;
148
+  complex<DP> Fn_K_0_G_0 = 0.0;
149
+  complex<DP> Prod_powerN = 0.0;
150
+  complex<DP> Fn_K_1_G_2 = 0.0;
151
+  //complex<DP> two_over_A_lambda_sq_plus_1over2sq;
152
+
153
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
154
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
155
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
156
+	
157
+	index_b = 0;
158
+
159
+	//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)) *
160
+	//				  (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
161
+	
162
+	for (int k = 0; k < B.chain.Nstrings; ++k) {
163
+	  for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
164
+	    for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
165
+
166
+	      if (B.chain.Str_L[k] == 1) {
167
+
168
+		// use simplified code for one-string here:  original form of Hm2P matrix
169
+
170
+		Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
171
+		  exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
172
+		Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
173
+		  exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
174
+
175
+		//Prod_powerN = pow((B.lambda[k][beta]  + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (B.chain.Nsites));
176
+		Prod_powerN = pow((B.lambda[k][beta]  + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (A.chain.Nsites));  // careful !  
177
+
178
+		Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
179
+		  //- two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
180
+		  ;
181
+	      }
182
+	      
183
+	      else {
184
+
185
+		if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
186
+		else if (b == B.chain.Str_L[k]) {
187
+		  
188
+		  Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
189
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
190
+		  
191
+		  Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
192
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
193
+
194
+		  sum1 = 0.0;
195
+		  
196
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
197
+		  
198
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) 
199
+		    * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] 
200
+			  - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
201
+		  
202
+		  for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) 
203
+		    
204
+		    sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
205
+		      exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
206
+		  
207
+		  //sum2 = 0.0;
208
+		  
209
+		  //for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)  sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
210
+		  
211
+		  prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
212
+
213
+		  for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)  
214
+		    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
215
+
216
+		  //Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq);
217
+		  Hm2P[index_a][index_b] = prod_num * sum1;
218
+
219
+		} // else if (b == B.chain.Str_L[k])
220
+	      } // else 
221
+
222
+	      index_b++;
223
+	    }}} // sums over k, beta, b
224
+
225
+	index_a++;
226
+      }}} // sums over j, alpha, a
227
+
228
+  //cout << "Matrix: " << endl;
229
+  //Hm2P.Print();
230
+
231
+  complex<DP> det = lndet_LU_CX_dstry(Hm2P);
232
+
233
+  /*
234
+  complex<DP> ln_form_factor_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
235
+    //    + 2.0 * real(lndet_LU_CX_dstry(Hm2P)) 
236
+    + 2.0 * det
237
+    - A.lnnorm - B.lnnorm;
238
+
239
+  //cout << "ln_SZ: " << endl << ln_prod1 << "\t" << -ln_prod2 << "\t" << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det 
240
+  //   << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
241
+
242
+  return(ln_form_factor_sq);
243
+  */
244
+  complex<DP> ln_overlap = 0.5 * (-ln_prod3 + ln_prod4) + det - 0.5 * (A.lnnorm + B.lnnorm);
245
+
246
+  cout << "ln_overlap: " << endl << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det 
247
+       << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
248
+
249
+  return(ln_overlap);
250
+
251
+}
252
+
253
+} // namespace JSC

+ 239
- 0
src/HEIS/ln_Smin_ME_XXX.cc View File

@@ -0,0 +1,239 @@
1
+#include "JSC.h"
2
+
3
+using namespace JSC;
4
+
5
+namespace JSC {
6
+
7
+inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
8
+{
9
+  complex<DP> ans = 0.0;
10
+
11
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
12
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
13
+      for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
14
+
15
+	if (!((j == k) && (alpha == beta) && (a == b))) 
16
+	  ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
17
+		     + 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))); 
18
+      }
19
+    }
20
+  } 
21
+
22
+  return(ans);
23
+}
24
+
25
+inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
26
+{
27
+  complex<DP> ans = 0.0;
28
+
29
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
30
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
31
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
32
+
33
+	ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
34
+		   + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
35
+      }
36
+    }
37
+  }
38
+
39
+  return(ans);
40
+}
41
+
42
+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)
43
+{
44
+  return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
45
+	       + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
46
+	      * (A.lambda[j][alpha] - B.lambda[k][beta]
47
+		 + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
48
+}
49
+
50
+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)
51
+{
52
+  return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
53
+		      + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5)) 
54
+		      )) 
55
+	  * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
56
+}
57
+
58
+complex<DP> ln_Smin_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
59
+{
60
+  // This function returns the natural log of the S^- operator matrix element.
61
+  // The A and B states can contain strings.
62
+
63
+  // Check that the two states are compatible
64
+
65
+  if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Smin matrix element.");
66
+
67
+  // Check that A and B are Mdown-compatible:  
68
+
69
+  if (A.base.Mdown != B.base.Mdown + 1) JSCerror("Incompatible Mdown between the two states in Smin matrix element!");
70
+
71
+  // Some convenient arrays
72
+
73
+  Lambda re_ln_Fn_F_B_0(B.chain, B.base);
74
+  Lambda im_ln_Fn_F_B_0(B.chain, B.base);
75
+  Lambda re_ln_Fn_G_0(B.chain, B.base);
76
+  Lambda im_ln_Fn_G_0(B.chain, B.base);
77
+  Lambda re_ln_Fn_G_2(B.chain, B.base);
78
+  Lambda im_ln_Fn_G_2(B.chain, B.base);
79
+
80
+  complex<DP> ln_prod1 = 0.0;
81
+  complex<DP> ln_prod2 = 0.0;
82
+  complex<DP> ln_prod3 = 0.0;
83
+  complex<DP> ln_prod4 = 0.0;
84
+
85
+  for (int i = 0; i < A.chain.Nstrings; ++i) 
86
+    for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
87
+      for (int a = 1; a <= A.chain.Str_L[i]; ++a)
88
+	ln_prod1 += log(norm(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
89
+
90
+  for (int i = 0; i < B.chain.Nstrings; ++i) 
91
+    for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
92
+      for (int a = 1; a <= B.chain.Str_L[i]; ++a)
93
+	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)
94
+	  ln_prod2 += log(norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
95
+
96
+  // Define the F ones earlier...
97
+
98
+  complex<DP> ln_FB0, ln_FG0, ln_FG2;
99
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
100
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
101
+      //re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
102
+      //im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
103
+      ln_FB0 = ln_Fn_F(B, j, alpha, 0);
104
+      re_ln_Fn_F_B_0[j][alpha] = real(ln_FB0);
105
+      im_ln_Fn_F_B_0[j][alpha] = imag(ln_FB0);
106
+      //re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
107
+      //im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
108
+      ln_FG0 = ln_Fn_G(A, B, j, alpha, 0);
109
+      re_ln_Fn_G_0[j][alpha] = real(ln_FG0);
110
+      im_ln_Fn_G_0[j][alpha] = imag(ln_FG0);
111
+      //re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
112
+      //im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
113
+      ln_FG2 = ln_Fn_G(A, B, j, alpha, 2);
114
+      re_ln_Fn_G_2[j][alpha] = real(ln_FG2);
115
+      im_ln_Fn_G_2[j][alpha] = imag(ln_FG2);
116
+    }
117
+  }
118
+
119
+  // Define regularized products in prefactors
120
+
121
+  for (int j = 0; j < A.chain.Nstrings; ++j)
122
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
123
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) 
124
+	ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);  
125
+
126
+  //  ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
127
+
128
+  for (int k = 0; k < B.chain.Nstrings; ++k)
129
+    for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
130
+      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
131
+	if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
132
+	else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
133
+    }
134
+  
135
+  //  ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
136
+
137
+  // Now proceed to build the Hm matrix
138
+
139
+  SQMat_CX Hm(0.0, A.base.Mdown);
140
+
141
+  int index_a = 0;
142
+  int index_b = 0;
143
+
144
+  complex<DP> sum1 = 0.0;
145
+  complex<DP> sum2 = 0.0;
146
+  complex<DP> prod_num = 0.0;
147
+  complex<DP> Fn_K_0_G_0 = 0.0;
148
+  complex<DP> Prod_powerN = 0.0;
149
+  complex<DP> Fn_K_1_G_2 = 0.0;
150
+  complex<DP> one_over_A_lambda_sq_plus_1over2sq;
151
+
152
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
153
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
154
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
155
+	
156
+	index_b = 0;
157
+	
158
+	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)) * 
159
+						  (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
160
+
161
+	for (int k = 0; k < B.chain.Nstrings; ++k) {
162
+	  for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
163
+	    for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
164
+
165
+	      if (B.chain.Str_L[k] == 1) {
166
+
167
+		// use simplified code for one-string here:  original form of Hm2P matrix
168
+
169
+		Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * 
170
+		  exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
171
+		Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) * 
172
+		  exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
173
+
174
+		Prod_powerN = pow((B.lambda[k][beta] + II * 0.5) /(B.lambda[k][beta] - II * 0.5), complex<DP> (B.chain.Nsites));
175
+
176
+		Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
177
+
178
+	      } // if (B.chain.Str_L == 1)
179
+	      
180
+	      else {
181
+
182
+		if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
183
+		else if (b == B.chain.Str_L[k]) {
184
+		  
185
+		  Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
186
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
187
+		  
188
+		  Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
189
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
190
+		  
191
+		  sum1 = 0.0;
192
+		  
193
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
194
+		  
195
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) 
196
+		    * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] 
197
+			  - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
198
+		  
199
+		  for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) 
200
+		    
201
+		    sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
202
+		      exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
203
+		  
204
+		  /*
205
+		  sum2 = 0.0;
206
+		  
207
+		  for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)  sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
208
+		  
209
+		  */
210
+		  prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
211
+
212
+		  for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)  
213
+		    prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1))); 
214
+		  // include all string contributions F_B_0 in this term
215
+
216
+		  Hm[index_a][index_b] = prod_num * sum1;
217
+
218
+		} // else if (b == B.chain.Str_L[k])
219
+	      } // else 
220
+
221
+	      index_b++;
222
+	    }}} // sums over k, beta, b
223
+
224
+	// now define the elements Hm[a][M]
225
+
226
+	Hm[index_a][B.base.Mdown] = one_over_A_lambda_sq_plus_1over2sq;  
227
+
228
+	index_a++;
229
+      }}} // sums over j, alpha, a
230
+
231
+  complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
232
+    + 2.0 * real(lndet_LU_CX_dstry(Hm)) - A.lnnorm - B.lnnorm;
233
+
234
+  //return(ln_ME_sq);
235
+  return(0.5 * ln_ME_sq); // Return ME, not MEsq
236
+
237
+}
238
+
239
+} // namespace JSC

+ 328
- 0
src/HEIS/ln_Smin_ME_XXZ.cc View File

@@ -0,0 +1,328 @@
1
+#include "JSC.h"
2
+
3
+using namespace JSC;
4
+
5
+namespace JSC {
6
+
7
+inline complex<DP> ln_Fn_F (XXZ_Bethe_State& B, int k, int beta, int b)
8
+{
9
+  complex<DP> ans = 0.0;
10
+  complex<DP> prod_temp = 1.0;
11
+  int counter = 0;
12
+  int arg = 0;
13
+  int absarg = 0;
14
+  int par_comb_1, par_comb_2;
15
+
16
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
17
+
18
+    par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
19
+    par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
20
+
21
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
22
+      for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
23
+
24
+	if (!((j == k) && (alpha == beta) && (a == b))) {
25
+
26
+	  arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
27
+	  absarg = abs(arg);
28
+	  /*	  
29
+	  prod_temp *= 0.5 * //done later...
30
+	    ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
31
+	     * (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k]) 
32
+		- sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
33
+			+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
34
+			* (sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
35
+			   + B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
36
+	  */
37
+
38
+	  prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
39
+			* (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)
40
+			+ II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
41
+			* (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));
42
+	}
43
+
44
+	if (counter++ > 100) {  // we do at most 100 products before taking a log
45
+	  ans += log(prod_temp);
46
+	  prod_temp = 1.0;
47
+	  counter = 0;
48
+	}
49
+
50
+      }}}
51
+
52
+  return(ans + log(prod_temp));
53
+}
54
+
55
+inline complex<DP> ln_Fn_G (XXZ_Bethe_State& A, XXZ_Bethe_State& B, int k, int beta, int b)
56
+{
57
+  complex<DP> ans = 0.0;
58
+  complex<DP> prod_temp = 1.0;
59
+  int counter = 0;
60
+  int arg = 0;
61
+  int absarg = 0;
62
+  int par_comb_1, par_comb_2;
63
+
64
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
65
+
66
+    par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
67
+    par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
68
+
69
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
70
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
71
+
72
+	arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
73
+	absarg = abs(arg);
74
+	/*
75
+	prod_temp *= 0.5 * //done later...
76
+	  ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
77
+		      * (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
78
+			 - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j]))
79
+		      + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
80
+		      * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
81
+			 + A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) );
82
+	*/
83
+	prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
84
+		      * (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)
85
+		      + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
86
+		      * (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));
87
+
88
+	if (counter++ > 100) {  // we do at most 100 products before taking a log
89
+	  ans += log(prod_temp);
90
+	  prod_temp = 1.0;
91
+	  counter = 0;
92
+	}
93
+      }}}
94
+
95
+  return(ans + log(prod_temp));
96
+}
97
+
98
+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)
99
+{
100
+  int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
101
+  int absarg1 = abs(arg1);
102
+  int arg2 = arg1 + 2;
103
+  int absarg2 = abs(arg2);
104
+
105
+  return(4.0/(
106
+	      ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
107
+		      * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
108
+			 - sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
109
+		      + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
110
+		      * (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
111
+			 + A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
112
+	 *
113
+	 ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
114
+		      * (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
115
+			 - sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
116
+		      + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
117
+		      * (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
118
+			 + A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
119
+	      ));
120
+
121
+}
122
+
123
+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)
124
+{
125
+  return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
126
+		      + 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5)) 
127
+		      + 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k]))) 
128
+	  * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
129
+}
130
+
131
+complex<DP> ln_Smin_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B)
132
+{
133
+  // This function returns the natural log of the S^- operator matrix element.
134
+  // The A and B states can contain strings.
135
+
136
+  // Check that the two states are compatible
137
+
138
+  if (A.chain != B.chain) JSCerror("Incompatible XXZ_Chains in Smin matrix element.");
139
+
140
+  // Check that A and B are Mdown-compatible:  
141
+
142
+  if (A.base.Mdown != B.base.Mdown + 1) {
143
+    cout << "A.base.Mdown = " << A.base.Mdown << "\tB.base.Mdown = " << B.base.Mdown << endl;
144
+    cout << "A: " << A << endl << "B: " << B << endl;
145
+    JSCerror("Incompatible Mdown between the two states in Smin matrix element!");
146
+  }
147
+
148
+  // Compute the sinh and cosh of rapidities
149
+
150
+  A.Compute_sinhlambda();
151
+  A.Compute_coshlambda();
152
+  B.Compute_sinhlambda();
153
+  B.Compute_coshlambda();
154
+
155
+  // Some convenient arrays
156
+
157
+  Lambda re_ln_Fn_F_B_0(B.chain, B.base);
158
+  Lambda im_ln_Fn_F_B_0(B.chain, B.base);
159
+  Lambda re_ln_Fn_G_0(B.chain, B.base);
160
+  Lambda im_ln_Fn_G_0(B.chain, B.base);
161
+  Lambda re_ln_Fn_G_2(B.chain, B.base);
162
+  Lambda im_ln_Fn_G_2(B.chain, B.base);
163
+
164
+  complex<DP> ln_prod1 = 0.0;
165
+  complex<DP> ln_prod2 = 0.0;
166
+  complex<DP> ln_prod3 = 0.0;
167
+  complex<DP> ln_prod4 = 0.0;
168
+
169
+  for (int i = 0; i < A.chain.Nstrings; ++i) 
170
+    for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
171
+      for (int a = 1; a <= A.chain.Str_L[i]; ++a)
172
+	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)
173
+				  + 0.25 * II * PI * (1.0 - A.chain.par[i]))));
174
+
175
+  for (int i = 0; i < B.chain.Nstrings; ++i) 
176
+    for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
177
+      for (int a = 1; a <= B.chain.Str_L[i]; ++a)
178
+	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)
179
+		      + 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
180
+	  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)
181
+				    + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
182
+
183
+  // Define the F ones earlier...
184
+
185
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
186
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
187
+      re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
188
+      im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
189
+      re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
190
+      im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
191
+      re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
192
+      im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
193
+    }
194
+  }
195
+
196
+  DP logabssinzeta = log(abs(sin(A.chain.anis)));
197
+
198
+  // Define regularized products in prefactors
199
+
200
+  for (int j = 0; j < A.chain.Nstrings; ++j)
201
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
202
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) 
203
+	ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);  // assume only one-strings here
204
+
205
+  ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
206
+
207
+  for (int k = 0; k < B.chain.Nstrings; ++k)
208
+    for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
209
+      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
210
+	if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
211
+	else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
212
+    }
213
+  
214
+  ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
215
+
216
+  // Now proceed to build the Hm matrix
217
+
218
+  SQMat_CX Hm(0.0, A.base.Mdown);
219
+
220
+  int index_a = 0;
221
+  int index_b = 0;
222
+
223
+  complex<DP> sum1 = 0.0;
224
+  complex<DP> sum2 = 0.0;
225
+  complex<DP> prod_num = 0.0;
226
+  complex<DP> Fn_K_0_G_0 = 0.0;
227
+  complex<DP> Prod_powerN = 0.0;
228
+  complex<DP> Fn_K_1_G_2 = 0.0;
229
+  complex<DP> one_over_A_sinhlambda_sq_plus_sinzetaover2sq;
230
+
231
+
232
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
233
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
234
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
235
+	
236
+	index_b = 0;
237
+	
238
+	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)
239
+								  + 0.25 * II * PI * (1.0 - A.chain.par[j]))) 
240
+							    * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
241
+								  + 0.25 * II * PI * (1.0 - A.chain.par[j])))
242
+							    + pow(sin(0.5*A.chain.anis), 2.0));
243
+
244
+	for (int k = 0; k < B.chain.Nstrings; ++k) {
245
+	  for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
246
+	    for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
247
+
248
+	      if (B.chain.Str_L[k] == 1) {
249
+
250
+		// use simplified code for one-string here:  original form of Hm matrix
251
+
252
+		Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * 
253
+		  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);
254
+		Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) * 
255
+		  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);
256
+
257
+		Prod_powerN = pow( B.chain.par[k] == 1 ? 
258
+				   (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])
259
+				   /(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])
260
+				   :
261
+				   (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])
262
+				   /(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])
263
+				   , complex<DP> (B.chain.Nsites));
264
+
265
+		Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
266
+
267
+	      } // if (B.chain.Str_L == 1)
268
+	      
269
+	      else {
270
+
271
+		if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
272
+		else if (b == B.chain.Str_L[k]) {
273
+		  
274
+		  Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
275
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
276
+		  
277
+		  Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
278
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
279
+		  
280
+		  sum1 = 0.0;
281
+		  
282
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
283
+		  
284
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) 
285
+		    * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] 
286
+			  - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
287
+		  
288
+		  for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) 
289
+		    
290
+		    sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
291
+		      exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
292
+		  
293
+		  /*
294
+		  sum2 = 0.0;
295
+		  
296
+		  for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)  sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
297
+		  
298
+		  */
299
+		  prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
300
+
301
+		  for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)  
302
+		    prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinzeta); 
303
+		  // include all string contributions F_B_0 in this term
304
+
305
+		  Hm[index_a][index_b] = prod_num * sum1;
306
+
307
+		} // else if (b == B.chain.Str_L[k])
308
+	      } // else 
309
+
310
+	      index_b++;
311
+	    }}} // sums over k, beta, b
312
+
313
+	// now define the elements Hm[a][M]
314
+
315
+	Hm[index_a][B.base.Mdown] = one_over_A_sinhlambda_sq_plus_sinzetaover2sq;  
316
+
317
+	index_a++;
318
+      }}} // sums over j, alpha, a
319
+
320
+  complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4) 
321
+    + 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinzeta - A.lnnorm - B.lnnorm;
322
+
323
+  //return(ln_ME_sq);
324
+  return(0.5 * ln_ME_sq); // Return ME, not MEsq
325
+
326
+}
327
+
328
+} // namespace JSC

+ 303
- 0
src/HEIS/ln_Smin_ME_XXZ_gpd.cc View File

@@ -0,0 +1,303 @@
1
+#include "JSC.h"
2
+
3
+using namespace JSC;
4
+
5
+namespace JSC {
6
+
7
+inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
8
+{
9
+  complex<DP> ans = 0.0;
10
+  complex<DP> prod_temp = 1.0;
11
+  int counter = 0;
12
+
13
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
14
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
15
+      for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
16
+	/*
17
+	if (!((j == k) && (alpha == beta) && (a == b))) 
18
+	  ans += log(-II * sin(B.lambda[j][alpha] - B.lambda[k][beta]
19
+			    + 0.5 * II * B.chain.eta * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))));
20
+	*/
21
+
22
+	if (!((j == k) && (alpha == beta) && (a == b))) {
23
+
24
+	  //	  arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
25
+	  //	  absarg = abs(arg);
26
+	  
27
+	  prod_temp *= -II * (B.sinlambda[j][alpha] * B.coslambda[k][beta] - B.coslambda[j][alpha] * B.sinlambda[k][beta])
28
+	    * cosh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
29
+	    (B.coslambda[j][alpha] * B.coslambda[k][beta] + B.sinlambda[j][alpha] * B.sinlambda[k][beta]) 
30
+	    * sinh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
31
+
32
+	}
33
+
34
+
35
+	if (counter++ > 10) {  // we do at most 10 products before taking a log
36
+	  ans += log(prod_temp);
37
+	  prod_temp = 1.0;
38
+	  counter = 0;
39
+	}
40
+
41
+      }}}
42
+
43
+  //  return(ans);
44
+  return(ans + log(prod_temp));
45
+}
46
+
47
+inline complex<DP> ln_Fn_G (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
48
+{
49
+  complex<DP> ans = 0.0;
50
+  complex<DP> prod_temp = 1.0;
51
+  int counter = 0;
52
+
53
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
54
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
55
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
56
+	/*
57
+	prod_temp *= -II * sin(A.lambda[j][alpha] - B.lambda[k][beta]
58
+		    + 0.5 * II * B.chain.eta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
59
+	*/
60
+
61
+	//	arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
62
+	//	absarg = abs(arg);
63
+
64
+	prod_temp *= -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
65
+	  * cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
66
+	  (A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
67
+	  * sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
68
+
69
+	if (counter++ > 25) {  // we do at most 25 products before taking a log
70
+	  ans += log(prod_temp);
71
+	  prod_temp = 1.0;
72
+	  counter = 0;
73
+	}
74
+      }}}
75
+
76
+  //  return(ans);
77
+  return(ans + log(prod_temp));
78
+}
79
+
80
+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)
81
+{
82
+  /*
83
+  return(-1.0/(sin(A.lambda[j][alpha] - B.lambda[k][beta]
84
+		    + 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) 
85
+	      * sin(A.lambda[j][alpha] - B.lambda[k][beta]
86
+		    + 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)))));
87
+  */
88
+
89
+  //  int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
90
+  //  int absarg1 = abs(arg1);
91
+  //  int arg2 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b - 1);
92
+  //  int arg2 = arg1 + 2;
93
+  //  int absarg2 = abs(arg2);
94
+
95
+  return(1.0/(( -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
96
+	  * cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
97
+	  (A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
98
+	       * sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))) *
99
+	      (-II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
100
+	  * cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))) +
101
+	  (A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
102
+	       * sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))))));
103
+
104
+}
105
+
106
+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)
107
+{
108
+  /*
109
+  complex<DP> ans = -II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
110
+				+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5)))); 
111
+
112
+  return (ans * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
113
+  */
114
+  return (-II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
115
+		      + 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5)))) 
116
+	  * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
117
+}
118
+
119
+complex<DP> ln_Smin_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B)
120
+{
121
+  // This function returns the natural log of the S^- operator matrix element.
122
+  // The A and B states can contain strings.
123
+
124
+  // Check that the two states refer to the same XXZ_gpd_Chain
125
+
126
+  if (A.chain != B.chain) JSCerror("Incompatible XXZ_gpd_Chains in Smin matrix element.");
127
+
128
+  // Check that A and B are compatible:  same Mdown
129
+
130
+  if (A.base.Mdown != B.base.Mdown + 1) JSCerror("Incompatible Mdown between the two states in Smin matrix element!");
131
+
132
+  // Compute the sin and cos of rapidities
133
+
134
+  A.Compute_sinlambda();
135
+  A.Compute_coslambda();
136
+  B.Compute_sinlambda();
137
+  B.Compute_coslambda();
138
+
139
+  // Some convenient arrays
140
+
141
+  Lambda re_ln_Fn_F_B_0(B.chain, B.base);
142
+  Lambda im_ln_Fn_F_B_0(B.chain, B.base);
143
+  Lambda re_ln_Fn_G_0(B.chain, B.base);
144
+  Lambda im_ln_Fn_G_0(B.chain, B.base);
145
+  Lambda re_ln_Fn_G_2(B.chain, B.base);
146
+  Lambda im_ln_Fn_G_2(B.chain, B.base);
147
+
148
+  complex<DP> ln_prod1 = 0.0;
149
+  complex<DP> ln_prod2 = 0.0;
150
+  complex<DP> ln_prod3 = 0.0;
151
+  complex<DP> ln_prod4 = 0.0;
152
+
153
+  for (int i = 0; i < A.chain.Nstrings; ++i) 
154
+    for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
155
+      for (int a = 1; a <= A.chain.Str_L[i]; ++a)
156
+	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))));
157
+
158
+  for (int i = 0; i < B.chain.Nstrings; ++i) 
159
+    for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
160
+      for (int a = 1; a <= B.chain.Str_L[i]; ++a)
161
+	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)
162
+	  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))));
163
+
164
+  //  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));
165
+
166
+  // Define the F ones earlier...
167
+
168
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
169
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
170
+      re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
171
+      im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
172
+      re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
173
+      im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
174
+      re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
175
+      im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
176
+    }
177
+  }
178
+
179
+  DP logabssinheta = log(abs(sinh(A.chain.anis)));
180
+
181
+  // Define regularized products in prefactors
182
+
183
+  for (int j = 0; j < A.chain.Nstrings; ++j)
184
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
185
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) 
186
+	ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);  
187
+
188
+  ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis)));
189
+
190
+  for (int k = 0; k < B.chain.Nstrings; ++k)
191
+    for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
192
+      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
193
+	if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
194
+	else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
195
+    }
196
+  
197
+  ln_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis)));
198
+
199
+  // Now proceed to build the Hm matrix
200
+
201
+  SQMat_CX Hm(0.0, A.base.Mdown);
202
+
203
+  int index_a = 0;
204
+  int index_b = 0;
205
+
206
+  complex<DP> sum1 = 0.0;
207
+  complex<DP> sum2 = 0.0;
208
+  complex<DP> prod_num = 0.0;
209
+  complex<DP> Fn_K_0_G_0 = 0.0;
210
+  complex<DP> Prod_powerN = 0.0;
211
+  complex<DP> Fn_K_1_G_2 = 0.0;
212
+  complex<DP> one_over_A_sinlambda_sq_plus_sinhetaover2sq = 0.0;
213
+
214
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
215
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
216
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
217
+	
218
+	index_b = 0;
219
+	
220
+	one_over_A_sinlambda_sq_plus_sinhetaover2sq = -1.0/((sin(A.lambda[j][alpha] // minus sign:  from 1/(sinh^2... to -1/(sin^2...
221
+								 + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a))) *
222
+							    (sin(A.lambda[j][alpha] // minus sign:  from 1/(sinh^2... to -1/(sin^2...
223
+								 + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a))) 
224
+							    + pow(sinh(0.5*A.chain.anis), 2.0));
225
+	
226
+	for (int k = 0; k < B.chain.Nstrings; ++k) {
227
+	  for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
228
+	    for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
229
+
230
+	      if (B.chain.Str_L[k] == 1) {
231
+
232
+		// use simplified code for one-string here:  original form of Hm2P matrix
233
+
234
+		Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * 
235
+		  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);
236
+		Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) * 
237
+		  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);
238
+
239
+		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])
240
+				  /(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]), 
241
+				  complex<DP> (B.chain.Nsites));
242
+
243
+		Hm[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2;
244
+	      }
245
+	      
246
+	      else {
247
+
248
+		if (b <= B.chain.Str_L[k] - 1) Hm[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
249
+		else if (b == B.chain.Str_L[k]) {
250
+		  
251
+		  Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
252
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
253
+		  
254
+		  Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
255
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
256
+		  
257
+		  sum1 = 0.0;
258
+		  
259
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
260
+		  
261
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) 
262
+		    * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] 
263
+			  - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
264
+		  
265
+		  for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) 
266
+		    
267
+		    sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
268
+		      exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
269
+		  /*		  
270
+		  sum2 = 0.0;
271
+		  
272
+		  for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)  sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
273
+		  */		  
274
+		  prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinheta);
275
+
276
+		  for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)  
277
+		    prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinheta); 
278
+		  // include all string contributions F_B_0 in this term
279
+
280
+		  Hm[index_a][index_b] = prod_num * sum1;
281
+
282
+		} // else if (b == B.chain.Str_L[k])
283
+	      } // else 
284
+
285
+	      index_b++;
286
+	    }}} // sums over k, beta, b
287
+
288
+	// now define the elements Hm[a][M]
289
+
290
+	Hm[index_a][B.base.Mdown] = one_over_A_sinlambda_sq_plus_sinhetaover2sq;  
291
+
292
+	index_a++;
293
+      }}} // sums over j, alpha, a
294
+
295
+  complex<DP> ln_ME_sq = log(1.0 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
296
+    + 2.0 * real(lndet_LU_CX_dstry(Hm)) + logabssinheta - A.lnnorm - B.lnnorm;
297
+
298
+  //return(ln_ME_sq);
299
+  return(0.5 * ln_ME_sq); // Return ME, not MEsq
300
+
301
+}
302
+
303
+} // namespace JSC

+ 307
- 0
src/HEIS/ln_Smm_ME_XXX.cc View File

@@ -0,0 +1,307 @@
1
+#include "JSC.h"
2
+
3
+using namespace JSC;
4
+
5
+namespace JSC {
6
+inline   complex<DP> phi(complex<DP> x){return x;}
7
+inline   complex<DP> a(complex<DP> x){return 1;}
8
+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);}
9
+inline   complex<DP> d(complex<DP> x, complex<DP> xi, complex<DP> eta, int N){return pow(b(x,xi,eta),N);}
10
+
11
+
12
+inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
13
+{
14
+  complex<DP> ans = 0.0;
15
+
16
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
17
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
18
+      for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
19
+
20
+	if (!((j == k) && (alpha == beta) && (a == b))) 
21
+	  ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
22
+		     + 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))); 
23
+      }
24
+    }
25
+  } 
26
+
27
+  return(ans);
28
+}
29
+
30
+inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
31
+{
32
+  complex<DP> ans = 0.0;
33
+
34
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
35
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
36
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
37
+
38
+	ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
39
+		   + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
40
+
41
+      }
42
+    }
43
+
44
+  }
45
+
46
+  return(ans);
47
+}
48
+
49
+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)
50
+{
51
+
52
+  return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
53
+	       + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
54
+	      * (A.lambda[j][alpha] - B.lambda[k][beta]
55
+		 + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
56
+  
57
+}
58
+
59
+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)
60
+{
61
+  return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
62
+		      + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5)) 
63
+		      )) 
64
+	  * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
65
+}
66
+
67
+
68
+complex<DP> ln_Smm_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
69
+{
70
+ const DP Zero_Center_Thres=1.0e-5;
71
+const DP real_dev=1.0e-14;
72
+ const DP Diff_ME_Thres=1.e-6;
73
+
74
+ //clock_t start_time_local = clock();
75
+
76
+  // This function returns the natural log of the S^z operator matrix element.
77
+  // The A and B states can contain strings.
78
+// A is the reference state.
79
+
80
+  // Check that the two states refer to the same XXX_Chain
81
+
82
+  if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Smm matrix element.");
83
+
84
+  // Check that A and B are compatible:  same Mdown
85
+
86
+  if (A.base.Mdown != B.base.Mdown + 2) JSCerror("Incompatible Mdown between the two states in Smm matrix element!");
87
+  
88
+  //if(B.String_delta()> HEIS_deltaprec) return(complex<DP>(-300.0)); // DEPRECATED in ++T_9
89
+
90
+
91
+  //if (B.type_id > 999999LL) return(complex<DP>(-300.0));
92
+
93
+  // Some convenient arrays
94
+  complex<DP> eta=-II;
95
+  complex<DP> ln_prod = complex<DP>(0.0,0.0);
96
+  complex<DP> result=-300;
97
+  complex<DP> prev_result=-300;
98
+  
99
+XXX_Bethe_State B_origin; B_origin=B;
100
+  bool zero_string=false;
101
+  for (int j = 0; j < B_origin.chain.Nstrings; ++j) 
102
+    for (int alpha = 0; alpha < B_origin.base.Nrap[j]; ++alpha)
103
+      if(abs(B_origin.lambda[j][alpha])<Zero_Center_Thres) zero_string=true;
104
+  
105
+  // Some convenient arrays
106
+  bool real_dev_conv=false;
107
+  int dev=-1;
108
+  while(!real_dev_conv){
109
+    real_dev_conv=true;
110
+    
111
+    dev++;
112
+    //add a delta to the origin of the centered strings
113
+    if(zero_string){
114
+      real_dev_conv=false;  
115
+      for (int j = 0; j < B.chain.Nstrings; ++j) 
116
+	for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha)
117
+	  if(abs(B_origin.lambda[j][alpha])<Zero_Center_Thres)
118
+	    B.lambda[j][alpha]=real_dev*pow(10.0,dev);
119
+    } 
120
+    
121
+    prev_result=result;
122
+
123
+
124
+
125
+  result=log(B.chain.Nsites*1.0);
126
+
127
+  int sizeA=0;
128
+int sizeB=0;
129
+  
130
+  for (int i = 0; i < A.chain.Nstrings; ++i) 
131
+    sizeA+=A.base.Nrap[i]*A.chain.Str_L[i];
132
+  for (int i = 0; i < B.chain.Nstrings; ++i) 
133
+    sizeB+=B.base.Nrap[i]*B.chain.Str_L[i];	
134
+
135
+  complex<DP>* mu = new complex<DP>[sizeA];
136
+  complex<DP>* lam = new complex<DP>[sizeB];
137
+  int index=0;
138
+  for (int i = 0; i < A.chain.Nstrings; ++i) 
139
+    for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
140
+      for (int a = 1; a <= A.chain.Str_L[i]; ++a)
141
+	{
142
+	  mu[index]=(A.lambda[i][alpha] + 0.5 * -eta * (A.chain.Str_L[i] + 1.0 - 2.0 * a));
143
+	  index++;
144
+	}
145
+
146
+index=0;
147
+  for (int i = 0; i < B.chain.Nstrings; ++i) 
148
+    for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
149
+      for (int a = 1; a <= B.chain.Str_L[i]; ++a)
150
+	{
151
+	  lam[index]=(B.lambda[i][alpha] + 0.5 * -eta * (B.chain.Str_L[i] + 1.0 - 2.0 * a));
152
+	  index++;
153
+	}
154
+
155
+ Lambda re_ln_Fn_F_B_0(B.chain, B.base);
156
+  Lambda im_ln_Fn_F_B_0(B.chain, B.base);
157
+  Lambda re_ln_Fn_G_0(B.chain, B.base);
158
+  Lambda im_ln_Fn_G_0(B.chain, B.base);
159
+  Lambda re_ln_Fn_G_2(B.chain, B.base);
160
+  Lambda im_ln_Fn_G_2(B.chain, B.base);
161
+
162
+for (int j = 0; j < B.chain.Nstrings; ++j) {
163
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
164
+      re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
165
+      im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
166
+      re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
167
+      im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
168
+      re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
169
+      im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2)); 
170
+    }
171
+  }
172
+
173
+  complex<DP> ln_prod1 = 0.0;
174
+  complex<DP> ln_prod2 = 0.0;
175
+  complex<DP> ln_prod3 = 0.0;
176
+  complex<DP> ln_prod4 = 0.0;
177
+
178
+  for (int i = 0; i < A.chain.Nstrings; ++i) 
179
+    for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
180
+      for (int a = 1; a <= A.chain.Str_L[i]; ++a)
181
+	ln_prod1 += log(norm(A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
182
+
183
+  for (int i = 0; i < B.chain.Nstrings; ++i) 
184
+    for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
185
+      for (int a = 1; a <= B.chain.Str_L[i]; ++a)
186
+	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)
187
+	  ln_prod2 += log(norm(B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0)));
188
+
189
+  // Define regularized products in prefactors
190
+  for (int j = 0; j < A.chain.Nstrings; ++j)
191
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
192
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) 
193
+	ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);  
194
+
195
+  for (int k = 0; k < B.chain.Nstrings; ++k)
196
+    for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
197
+      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
198
+	if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
199
+	else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
200
+    }  
201
+  result += 2.0*real(ln_prod1 - ln_prod2) - real(ln_prod3)  + real(ln_prod4)  - A.lnnorm - B.lnnorm;
202
+// Define the F ones earlier...
203
+
204
+  int index_a = 0;
205
+  int index_b = 0;
206
+  complex<DP> Prod_powerN;
207
+
208
+  //mu is the ground state!
209
+  //A -> mu, B -> lam
210
+SQMat_CX H(0.0, A.base.Mdown);
211
+ index_a = 0;
212
+  
213
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
214
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
215
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
216
+	
217
+	index_b = 0;
218
+
219
+	complex<DP> Da;
220
+	complex<DP> Ca;
221
+	Da=eta/((mu[index_a]-eta*0.5)*(mu[index_a]+eta*0.5));
222
+	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);
223
+	
224
+	
225
+	for (int k = 0; k < B.chain.Nstrings; ++k) {
226
+	  for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
227
+	    for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
228
+	      
229
+	      if (B.chain.Str_L[k] == 1) {
230
+
231
+
232
+		complex<DP> prodplus= complex<DP>(1.0,0.0);
233
+		complex<DP> prodminus= complex<DP>(1.0,0.0);
234
+
235
+		// use simplified code for one-string here:  original form of Hm2P matrix
236
+		prodplus = Fn_K (A, j, alpha, a, B, k, beta, 0);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]+eta) )
237
+		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]) |;
238
+
239
+		prodminus = Fn_K (A, j, alpha, a, B, k, beta, 1);// 1.0/ (phi(mu[l]-lam[k]) phi(mu[l]-lam[k]-eta) )
240
+	        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]) |;
241
+			
242
+		Prod_powerN = pow((B.lambda[k][beta] - eta*0.5) /(B.lambda[k][beta] + eta*0.5), complex<DP> (B.chain.Nsites));
243
+		H[index_a][index_b] =eta*(prodplus-prodminus*Prod_powerN);
244
+	      } // if (B.chain.Str_L == 1)
245
+	      
246
+	      else {
247
+		// */{
248
+	
249
+		if (b > 1){ 
250
+		  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]) |
251
+		}
252
+		else if (b == 1) {
253
+		  
254
+		  Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
255
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
256
+    
257
+		  Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
258
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
259
+		  
260
+		  complex<DP> sum1 = complex<DP>(0.0,0.0);
261
+		  
262
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) *exp(ln_FunctionG[0]+ ln_FunctionG[1] 
263
+			  - ln_FunctionF[0] - ln_FunctionF[1]);//sum term when i=0
264
+		  
265
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k])
266
+		    * exp( ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1]
267
+			- ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]); //sum term when i=n
268
+		  
269
+		  
270
+		  for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) { 
271
+		    sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
272
+		      exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
273
+		    
274
+		  }
275
+
276
+		  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_...)
277
+		} // else if (b == B.chain.Str_L[k])
278
+	      } // else 
279
+	      index_b++;
280
+	    }}} // sums over k, beta, b
281
+	
282
+	// now define the elements H[a][M] & H[a][M-1]
283
+	H[index_a][B.base.Mdown]=Da;	
284
+	H[index_a][B.base.Mdown+1]=Ca;
285
+	index_a++;
286
+	}}} // sums over j, alpha, a
287
+
288
+  complex<DP> logF=lndet_LU_CX_dstry(H);
289
+  result+=2.0*real(logF);
290
+  result+=log(2.0)-log((A.chain.Nsites-A.base.Mdown*2+3.0)*((A.chain.Nsites-A.base.Mdown*2+4.0)));
291
+  if (!(real_dev_conv) && abs(exp(result)-exp(prev_result))<abs( Diff_ME_Thres*exp(result)))
292
+    real_dev_conv=true;
293
+  
294
+  if (!(real_dev_conv) && dev >20){
295
+    result=-300;
296
+    real_dev_conv=true;
297
+  }
298
+
299
+ delete[] mu;
300
+ delete[] lam;
301
+
302
+  }
303
+  //return(result);
304
+  return(0.5 * result); // Return ME, not MEsq
305
+}
306
+  
307
+} // namespace JSC

+ 247
- 0
src/HEIS/ln_Sz_ME_XXX.cc View File

@@ -0,0 +1,247 @@
1
+/**********************************************************
2
+
3
+This software is part of J.-S. Caux's ABACUS++ library.
4
+
5
+Copyright (c)
6
+
7
+-----------------------------------------------------------
8
+
9
+***********************************************************/
10
+
11
+#include "JSC.h"
12
+
13
+using namespace JSC;
14
+
15
+namespace JSC {
16
+
17
+inline complex<DP> ln_Fn_F (XXX_Bethe_State& B, int k, int beta, int b)
18
+{
19
+  complex<DP> ans = 0.0;
20
+
21
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
22
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
23
+      for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
24
+
25
+	if (!((j == k) && (alpha == beta) && (a == b))) 
26
+	  ans += log(B.lambda[j][alpha] - B.lambda[k][beta]
27
+		     + 0.5 * II * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))); 
28
+      }
29
+    }
30
+  }
31
+
32
+  return(ans);
33
+}
34
+
35
+inline complex<DP> ln_Fn_G (XXX_Bethe_State& A, XXX_Bethe_State& B, int k, int beta, int b)
36
+{
37
+  complex<DP> ans = 0.0;
38
+
39
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
40
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
41
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
42
+
43
+	ans += log(A.lambda[j][alpha] - B.lambda[k][beta]
44
+		   + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
45
+      }
46
+    }
47
+  }
48
+
49
+  return(ans);
50
+}
51
+
52
+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)
53
+{
54
+  return(1.0/((A.lambda[j][alpha] - B.lambda[k][beta]
55
+	       + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))
56
+	      * (A.lambda[j][alpha] - B.lambda[k][beta]
57
+		 + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)) )));
58
+}
59
+
60
+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)
61
+{
62
+  return ((2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
63
+		      + 0.5 * II * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5)) 
64
+		      )) 
65
+	  * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
66
+}
67
+
68
+complex<DP> ln_Sz_ME (XXX_Bethe_State& A, XXX_Bethe_State& B)
69
+{
70
+  // This function returns the natural log of the S^z operator matrix element.
71
+  // The A and B states can contain strings.
72
+
73
+  // Check that the two states refer to the same XXX_Chain
74
+
75
+  if (A.chain != B.chain) JSCerror("Incompatible XXX_Chains in Sz matrix element.");
76
+
77
+  // Check that A and B are compatible:  same Mdown
78
+
79
+  if (A.base.Mdown != B.base.Mdown) JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
80
+
81
+  //if (A.iK == B.iK && (A.label != B.label))
82
+  if (A.iK == B.iK && (A.label.compare(B.label) != 0))
83
+    return(-300.0); // matrix element identically vanishes
84
+
85
+  // Some convenient arrays
86
+
87
+  Lambda re_ln_Fn_F_B_0(B.chain, B.base);
88
+  Lambda im_ln_Fn_F_B_0(B.chain, B.base);
89
+  Lambda re_ln_Fn_G_0(B.chain, B.base);
90
+  Lambda im_ln_Fn_G_0(B.chain, B.base);
91
+  Lambda re_ln_Fn_G_2(B.chain, B.base);
92
+  Lambda im_ln_Fn_G_2(B.chain, B.base);
93
+
94
+  complex<DP> ln_prod1 = 0.0;
95
+  complex<DP> ln_prod2 = 0.0;
96
+  complex<DP> ln_prod3 = 0.0;
97
+  complex<DP> ln_prod4 = 0.0;
98
+
99
+  for (int i = 0; i < A.chain.Nstrings; ++i) 
100
+    for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
101
+      for (int a = 1; a <= A.chain.Str_L[i]; ++a)
102
+	ln_prod1 += log(norm((A.lambda[i][alpha] + 0.5 * II * (A.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
103
+
104
+  for (int i = 0; i < B.chain.Nstrings; ++i) 
105
+    for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
106
+      for (int a = 1; a <= B.chain.Str_L[i]; ++a)
107
+	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)
108
+	  ln_prod2 += log(norm((B.lambda[i][alpha] + 0.5 * II * (B.chain.Str_L[i] + 1.0 - 2.0 * a - 1.0))));
109
+
110
+  // Define the F ones earlier...
111
+
112
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
113
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
114
+      re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
115
+      im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
116
+      re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
117
+      im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
118
+      re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
119
+      im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
120
+    }
121
+  }
122
+
123
+  // Define regularized products in prefactors
124
+
125
+  for (int j = 0; j < A.chain.Nstrings; ++j)
126
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
127
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) 
128
+	ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);  
129
+
130
+  //  ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.zeta)));
131
+
132
+  for (int k = 0; k < B.chain.Nstrings; ++k)
133
+    for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
134
+      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
135
+	if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
136
+	else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
137
+    }
138
+  
139
+  //  ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.zeta)));
140
+
141
+  // Now proceed to build the Hm2P matrix
142
+
143
+  SQMat_CX Hm2P(0.0, A.base.Mdown);
144
+
145
+  int index_a = 0;
146
+  int index_b = 0;
147
+
148
+  complex<DP> sum1 = 0.0;
149
+  complex<DP> sum2 = 0.0;
150
+  complex<DP> prod_num = 0.0;
151
+  complex<DP> Fn_K_0_G_0 = 0.0;
152
+  complex<DP> Prod_powerN = 0.0;
153
+  complex<DP> Fn_K_1_G_2 = 0.0;
154
+  complex<DP> two_over_A_lambda_sq_plus_1over2sq;
155
+
156
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
157
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
158
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
159
+	
160
+	index_b = 0;
161
+
162
+	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)) *
163
+						  (A.lambda[j][alpha] + 0.5 * II * (A.chain.Str_L[j] + 1.0 - 2.0 * a)) + 0.25);
164
+	
165
+	for (int k = 0; k < B.chain.Nstrings; ++k) {
166
+	  for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
167
+	    for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
168
+
169
+	      if (B.chain.Str_L[k] == 1) {
170
+
171
+		// use simplified code for one-string here:  original form of Hm2P matrix
172
+
173
+		Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) *
174
+		  exp(re_ln_Fn_G_0[k][beta] + II * im_ln_Fn_G_0[k][beta] - re_ln_Fn_F_B_0[k][beta]);
175
+		Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
176
+		  exp(re_ln_Fn_G_2[k][beta] + II * im_ln_Fn_G_2[k][beta] - re_ln_Fn_F_B_0[k][beta]);
177
+
178
+		Prod_powerN = pow((B.lambda[k][beta]  + 0.5 * II)/(B.lambda[k][beta] - 0.5 * II), complex<DP> (B.chain.Nsites));
179
+
180
+		Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2
181
+		  - two_over_A_lambda_sq_plus_1over2sq * exp(II*im_ln_Fn_F_B_0[k][beta]);
182
+
183
+	      }
184
+	      
185
+	      else {
186
+
187
+		if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
188
+		else if (b == B.chain.Str_L[k]) {
189
+		  
190
+		  Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
191
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
192
+		  
193
+		  Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
194
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
195
+
196
+		  sum1 = 0.0;
197
+		  
198
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
199
+		  
200
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) 
201
+		    * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] 
202
+			  - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
203
+		  
204
+		  for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) 
205
+		    
206
+		    sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
207
+		      exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
208
+		  
209
+		  sum2 = 0.0;
210
+		  
211
+		  for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)  sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
212
+		  
213
+		  prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]]);
214
+
215
+		  for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)  
216
+		    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
217
+
218
+		  Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_lambda_sq_plus_1over2sq);
219
+
220
+		} // else if (b == B.chain.Str_L[k])
221
+	      } // else 
222
+
223
+	      index_b++;
224
+	    }}} // sums over k, beta, b
225
+
226
+	index_a++;
227
+      }}} // sums over j, alpha, a
228
+
229
+  //cout << "Matrix: " << endl;
230
+  //Hm2P.Print();
231
+
232
+  DP det = real(lndet_LU_CX_dstry(Hm2P));
233
+
234
+  complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
235
+    //    + 2.0 * real(lndet_LU_CX_dstry(Hm2P)) 
236
+    + 2.0 * det
237
+    - A.lnnorm - B.lnnorm;
238
+
239
+  //cout << "ln_Sz: " << endl << ln_prod1 << "\t" << -ln_prod2 << "\t" << -ln_prod3 << "\t" << ln_prod4 << "\t" << 2.0 * det 
240
+  //   << "\t" << -A.lnnorm << "\t" << -B.lnnorm << endl;
241
+
242
+  //return(ln_ME_sq);
243
+  return(0.5 * ln_ME_sq); // Return ME, not MEsq
244
+
245
+}
246
+
247
+} // namespace JSC

+ 563
- 0
src/HEIS/ln_Sz_ME_XXZ.cc View File

@@ -0,0 +1,563 @@
1
+#include "JSC.h"
2
+
3
+using namespace JSC;
4
+
5
+namespace JSC {
6
+
7
+  inline complex<DP> ln_Fn_F (XXZ_Bethe_State& B, int k, int beta, int b)
8
+  {
9
+    complex<DP> ans = 0.0;
10
+    complex<DP> prod_temp = 1.0;
11
+    int counter = 0;
12
+    int arg = 0;
13
+    int absarg = 0;
14
+    int par_comb_1, par_comb_2;
15
+    
16
+    for (int j = 0; j < B.chain.Nstrings; ++j) {
17
+      
18
+      par_comb_1 = B.chain.par[j] == B.chain.par[k] ? 1 : 0;
19
+      par_comb_2 = B.chain.par[k] == B.chain.par[j] ? 0 : B.chain.par[k];
20
+      
21
+      for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
22
+	
23
+	for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
24
+	  
25
+	  if (!((j == k) && (alpha == beta) && (a == b))) {
26
+	    
27
+	    arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
28
+	    absarg = abs(arg);
29
+	    /*
30
+	      prod_temp *= 0.5 * 
31
+	      ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
32
+	      * (B.chain.co_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
33
+	      - sgn_int(arg) * B.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j]))
34
+	      + II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
35
+	      * (sgn_int(arg) 
36
+	      * B.chain.si_n_anis_over_2[absarg] * (1.0 + B.chain.par[j] * B.chain.par[k])
37
+	      + B.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - B.chain.par[j])) );
38
+	    */
39
+	    prod_temp *= ((B.sinhlambda[j][alpha] * B.coshlambda[k][beta] - B.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
40
+			  * (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)
41
+			  + II * (B.coshlambda[j][alpha] * B.coshlambda[k][beta] - B.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
42
+			  * (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));
43
+	    
44
+	  }
45
+	  
46
+	  if (counter++ > 100) {  // we do at most 100 products before taking a log
47
+	    ans += log(prod_temp);
48
+	    prod_temp = 1.0;
49
+	    counter = 0;
50
+	  }
51
+	  
52
+	}}}
53
+    
54
+    return(ans + log(prod_temp));
55
+  }
56
+  
57
+  inline complex<DP> ln_Fn_G (XXZ_Bethe_State& A, XXZ_Bethe_State& B, int k, int beta, int b)
58
+  {
59
+    complex<DP> ans = 0.0;
60
+    complex<DP> prod_temp = 1.0;
61
+    int counter = 0;
62
+    int arg = 0;
63
+    int absarg = 0;
64
+    int par_comb_1, par_comb_2;
65
+    
66
+    for (int j = 0; j < A.chain.Nstrings; ++j) {
67
+      
68
+      par_comb_1 = A.chain.par[j] == B.chain.par[k] ? 1 : 0;
69
+      par_comb_2 = B.chain.par[k] == A.chain.par[j] ? 0 : B.chain.par[k];
70
+      
71
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
72
+	
73
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
74
+	  
75
+	  arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
76
+	  absarg = abs(arg);
77
+	  
78
+	  /*
79
+	    prod_temp *= 0.5 * 
80
+	    ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
81
+	    * (A.chain.co_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
82
+	    - sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j]))
83
+	    + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
84
+	    * (sgn_int(arg) * A.chain.si_n_anis_over_2[absarg] * (1.0 + A.chain.par[j] * B.chain.par[k])
85
+	    + A.chain.co_n_anis_over_2[absarg] * (B.chain.par[k] - A.chain.par[j])) );
86
+	  */
87
+	  prod_temp *= ((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
88
+			* (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)
89
+			+ II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
90
+			* (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));
91
+	  
92
+	  if (counter++ > 100) {  // we do at most 100 products before taking a log
93
+	    ans += log(prod_temp);
94
+	    prod_temp = 1.0;
95
+	    counter = 0;
96
+	  }
97
+	}}}
98
+    
99
+    return(ans + log(prod_temp));
100
+  }
101
+  
102
+  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)
103
+  {
104
+    int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
105
+    int absarg1 = abs(arg1);
106
+    int arg2 = arg1 + 2;
107
+    int absarg2 = abs(arg2);
108
+    
109
+    return(4.0/(
110
+		((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
111
+		 * (A.chain.co_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
112
+		    - sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j]))
113
+		 + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
114
+		 * (sgn_int(arg1) * A.chain.si_n_anis_over_2[absarg1] * (1.0 + A.chain.par[j] * B.chain.par[k])
115
+		    + A.chain.co_n_anis_over_2[absarg1] * (B.chain.par[k] - A.chain.par[j])) )
116
+		*
117
+		((A.sinhlambda[j][alpha] * B.coshlambda[k][beta] - A.coshlambda[j][alpha] * B.sinhlambda[k][beta]) 
118
+		 * (A.chain.co_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
119
+		    - sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j]))
120
+		 + II * (A.coshlambda[j][alpha] * B.coshlambda[k][beta] - A.sinhlambda[j][alpha] * B.sinhlambda[k][beta]) 
121
+		 * (sgn_int(arg2) * A.chain.si_n_anis_over_2[absarg2] * (1.0 + A.chain.par[j] * B.chain.par[k])
122
+		    + A.chain.co_n_anis_over_2[absarg2] * (B.chain.par[k] - A.chain.par[j])) )
123
+		));
124
+    
125
+  }
126
+  
127
+  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)
128
+  {
129
+    return (sinh(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
130
+			+ 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5)) 
131
+			+ 0.25 * II * PI * complex<DP>(-A.chain.par[j] + B.chain.par[k]))) 
132
+	    * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
133
+  }
134
+  
135
+  
136
+  // Version without phases:
137
+  complex<DP> ln_Sz_ME (XXZ_Bethe_State& A, XXZ_Bethe_State& B)
138
+  {
139
+    // This function returns the natural log of the S^z operator matrix element.
140
+    // The A and B states can contain strings.
141
+    
142
+    // Check that the two states refer to the same XXZ_Chain
143
+    
144
+    if (A.chain != B.chain) {
145
+      JSCerror("Incompatible XXZ_Chains in Sz matrix element.");
146
+    }
147
+    
148
+    // Check that A and B are compatible:  same Mdown
149
+    
150
+    if (A.base.Mdown != B.base.Mdown) {
151
+      cout << "Bra state: " << endl << A << endl;
152
+      cout << "Ket state: " << endl << B << endl;
153
+      cout << A.base.Mdown << "\t" << B.base.Mdown << endl;
154
+      JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
155
+    }
156
+    
157
+    if (A.iK == B.iK && (A.label != B.label))
158
+      return(-300.0); // matrix element identically vanishes
159
+    
160
+    // Compute the sinh and cosh of rapidities
161
+    
162
+    A.Compute_sinhlambda();
163
+    A.Compute_coshlambda();
164
+    B.Compute_sinhlambda();
165
+    B.Compute_coshlambda();
166
+    
167
+    // Some convenient arrays
168
+    
169
+    Lambda re_ln_Fn_F_B_0(B.chain, B.base);
170
+    Lambda im_ln_Fn_F_B_0(B.chain, B.base);
171
+    Lambda re_ln_Fn_G_0(B.chain, B.base);
172
+    Lambda im_ln_Fn_G_0(B.chain, B.base);
173
+    Lambda re_ln_Fn_G_2(B.chain, B.base);
174
+    Lambda im_ln_Fn_G_2(B.chain, B.base);
175
+    
176
+    complex<DP> ln_prod1 = 0.0;
177
+    complex<DP> ln_prod2 = 0.0;
178
+    complex<DP> ln_prod3 = 0.0;
179
+    complex<DP> ln_prod4 = 0.0;
180
+    
181
+    for (int i = 0; i < A.chain.Nstrings; ++i) 
182
+      for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
183
+	for (int a = 1; a <= A.chain.Str_L[i]; ++a)
184
+	  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)
185
+				    + 0.25 * II * PI * (1.0 - A.chain.par[i]))));
186
+    
187
+    for (int i = 0; i < B.chain.Nstrings; ++i) 
188
+      for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
189
+	for (int a = 1; a <= B.chain.Str_L[i]; ++a)
190
+	  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)
191
+			+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
192
+	    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)
193
+				      + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
194
+    
195
+    // Define the F ones earlier...
196
+    
197
+    complex<DP> ln_Fn_F_B_0;
198
+    for (int j = 0; j < B.chain.Nstrings; ++j) {
199
+      for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
200
+	ln_Fn_F_B_0 = ln_Fn_F(B, j, alpha, 0);
201
+	//re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
202
+	//im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
203
+	re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F_B_0);
204
+	im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F_B_0);
205
+	re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
206
+	im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
207
+	re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
208
+	im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
209
+      }
210
+    }
211
+    
212
+    DP logabssinzeta = log(abs(sin(A.chain.anis)));
213
+    
214
+    // Define regularized products in prefactors
215
+    
216
+    for (int j = 0; j < A.chain.Nstrings; ++j)
217
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
218
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
219
+	  ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
220
+	}
221
+    
222
+    ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
223
+    
224
+    for (int k = 0; k < B.chain.Nstrings; ++k)
225
+      for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
226
+	for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
227
+	  if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
228
+	  else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
229
+	}
230
+    
231
+    ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
232
+    
233
+    // Now proceed to build the Hm2P matrix
234
+    
235
+    SQMat_CX Hm2P(0.0, A.base.Mdown);
236
+    
237
+    int index_a = 0;
238
+    int index_b = 0;
239
+    
240
+    complex<DP> sum1 = 0.0;
241
+    complex<DP> sum2 = 0.0;
242
+    complex<DP> prod_num = 0.0;
243
+    complex<DP> Fn_K_0_G_0 = 0.0;
244
+    complex<DP> Prod_powerN = 0.0;
245
+    complex<DP> Fn_K_1_G_2 = 0.0;
246
+    complex<DP> two_over_A_sinhlambda_sq_plus_sinzetaover2sq;
247
+    
248
+    
249
+    for (int j = 0; j < A.chain.Nstrings; ++j) {
250
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
251
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
252
+	  
253
+	  index_b = 0;
254
+	  
255
+	  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)
256
+								    + 0.25 * II * PI * (1.0 - A.chain.par[j]))) 
257
+							      * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
258
+								      + 0.25 * II * PI * (1.0 - A.chain.par[j]))) 
259
+							      + pow(sin(0.5*A.chain.anis), 2.0));
260
+	  
261
+	  for (int k = 0; k < B.chain.Nstrings; ++k) {
262
+	    for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
263
+	      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
264
+		
265
+		if (B.chain.Str_L[k] == 1) {
266
+		  
267
+		  // use simplified code for one-string here:  original form of Hm2P matrix
268
+		  
269
+		  Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * 
270
+		    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);
271
+		  Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
272
+		    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);
273
+		  
274
+		  Prod_powerN = pow( B.chain.par[k] == 1 ? 
275
+				     (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])
276
+				     /(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])
277
+				     :
278
+				     (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])
279
+				     /(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])
280
+				     , complex<DP> (B.chain.Nsites));
281
+		  
282
+		  //cout << "Prod_powerN = " << Prod_powerN << "\t" << abs(Prod_powerN) << endl;
283
+		  
284
+		  Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq
285
+		    * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinzeta);
286
+		  
287
+		}
288
+		
289
+		else {
290
+		  
291
+		  if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
292
+		  else if (b == B.chain.Str_L[k]) {
293
+		    
294
+		    Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
295
+		    for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
296
+		    
297
+		    Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
298
+		    for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
299
+		    
300
+		    sum1 = 0.0;
301
+		    
302
+		    sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
303
+		    
304
+		    sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) 
305
+		      * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] 
306
+			    - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
307
+		    
308
+		    for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) 
309
+		      
310
+		      sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
311
+			exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
312
+		    
313
+		    sum2 = 0.0;
314
+		    
315
+		    for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)  sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
316
+		    
317
+		    prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinzeta);
318
+		    
319
+		    for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)  
320
+		      prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logabssinzeta); 
321
+		    // include all string contributions F_B_0 in this term
322
+		    
323
+		    Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinhlambda_sq_plus_sinzetaover2sq);
324
+		    
325
+		  } // else if (b == B.chain.Str_L[k])
326
+		} // else 
327
+		
328
+		index_b++;
329
+	      }}} // sums over k, beta, b
330
+	  index_a++;
331
+	}}} // sums over j, alpha, a
332
+    
333
+    DP re_ln_det = real(lndet_LU_CX_dstry(Hm2P));
334
+    
335
+    complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
336
+      + 2.0 * /*real(lndet_LU_CX_dstry(Hm2P))*/ re_ln_det - A.lnnorm - B.lnnorm;
337
+    
338
+    //cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm 
339
+    //<< "\t" << re_ln_det << "\t" << ln_ME_sq << endl;
340
+    
341
+    //return(ln_ME_sq);
342
+    return(0.5 * ln_ME_sq); // Return ME, not MEsq
343
+    
344
+  }
345
+
346
+  // Version with phases:
347
+  complex<DP> ln_Sz_ME_with_phase (XXZ_Bethe_State& A, XXZ_Bethe_State& B)
348
+  {
349
+    // This function returns the natural log of the S^z operator matrix element.
350
+    // The A and B states can contain strings.
351
+    
352
+    // Check that the two states refer to the same XXZ_Chain
353
+    
354
+    if (A.chain != B.chain) JSCerror("Incompatible XXZ_Chains in Sz matrix element.");
355
+    
356
+    // Check that A and B are compatible:  same Mdown
357
+    
358
+    if (A.base.Mdown != B.base.Mdown) {
359
+      cout << "Bra state: " << endl << A << endl;
360
+      cout << "Ket state: " << endl << B << endl;
361
+      cout << A.base.Mdown << "\t" << B.base.Mdown << endl;
362
+      JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
363
+    }
364
+    
365
+    if (A.iK == B.iK && (A.label != B.label))
366
+      return(-300.0); // matrix element identically vanishes
367
+    
368
+    // Compute the sinh and cosh of rapidities
369
+    
370
+    A.Compute_sinhlambda();
371
+    A.Compute_coshlambda();
372
+    B.Compute_sinhlambda();
373
+    B.Compute_coshlambda();
374
+    
375
+    // Some convenient arrays
376
+    
377
+    Lambda re_ln_Fn_F_B_0(B.chain, B.base);
378
+    Lambda im_ln_Fn_F_B_0(B.chain, B.base);
379
+    Lambda re_ln_Fn_G_0(B.chain, B.base);
380
+    Lambda im_ln_Fn_G_0(B.chain, B.base);
381
+    Lambda re_ln_Fn_G_2(B.chain, B.base);
382
+    Lambda im_ln_Fn_G_2(B.chain, B.base);
383
+    
384
+    complex<DP> ln_prod1 = 0.0;
385
+    complex<DP> ln_prod2 = 0.0;
386
+    complex<DP> ln_prod3 = 0.0;
387
+    complex<DP> ln_prod4 = 0.0;
388
+    
389
+    for (int i = 0; i < A.chain.Nstrings; ++i) 
390
+      for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
391
+	for (int a = 1; a <= A.chain.Str_L[i]; ++a)
392
+	  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)
393
+				    + 0.25 * II * PI * (1.0 - A.chain.par[i])));
394
+
395
+    complex<DP> shB;
396
+    for (int i = 0; i < B.chain.Nstrings; ++i) 
397
+      for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
398
+	for (int a = 1; a <= B.chain.Str_L[i]; ++a)
399
+	  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)
400
+			+ 0.25 * II * PI * (1.0 - B.chain.par[i]))) > 100.0 * MACHINE_EPS_SQ)
401
+	    //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)
402
+	    //			      + 0.25 * II * PI * (1.0 - B.chain.par[i]))));
403
+	    ln_prod2 += log(shB);
404
+    
405
+    // Define the F ones earlier...
406
+    
407
+    complex<DP> ln_Fn_F_B_0, ln_Fn_G_0, ln_Fn_G_2;
408
+    for (int j = 0; j < B.chain.Nstrings; ++j) {
409
+      for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
410
+	//re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
411
+	//im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
412
+	ln_Fn_F_B_0 = ln_Fn_F(B, j, alpha, 0);
413
+	re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F_B_0);
414
+	im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F_B_0);
415
+    	//re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
416
+	//im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
417
+	ln_Fn_G_0 = ln_Fn_G(A, B, j, alpha, 0);
418
+    	re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G_0);
419
+	im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G_0);
420
+	//re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
421
+	//im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
422
+	ln_Fn_G_0 = ln_Fn_G(A, B, j, alpha, 2);
423
+	re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G_2);
424
+	im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G_2);
425
+      }
426
+    }
427
+    
428
+    DP logsinzeta = log(sin(A.chain.anis));
429
+    
430
+    // Define regularized products in prefactors
431
+    
432
+    for (int j = 0; j < A.chain.Nstrings; ++j)
433
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
434
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
435
+	  ln_prod3 += ln_Fn_F (A, j, alpha, a - 1);
436
+	}
437
+    
438
+    //ln_prod3 -= A.base.Mdown * log(abs(sin(A.chain.anis)));
439
+    ln_prod3 -= A.base.Mdown * logsinzeta;
440
+    
441
+    for (int k = 0; k < B.chain.Nstrings; ++k)
442
+      for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
443
+	for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
444
+	  if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
445
+	  else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
446
+	}
447
+    
448
+    //ln_prod4 -= B.base.Mdown * log(abs(sin(B.chain.anis)));
449
+    ln_prod4 -= B.base.Mdown * logsinzeta;
450
+    
451
+    // Now proceed to build the Hm2P matrix
452
+    
453
+    SQMat_CX Hm2P(0.0, A.base.Mdown);
454
+    
455
+    int index_a = 0;
456
+    int index_b = 0;
457
+    
458
+    complex<DP> sum1 = 0.0;
459
+    complex<DP> sum2 = 0.0;
460
+    complex<DP> prod_num = 0.0;
461
+    complex<DP> Fn_K_0_G_0 = 0.0;
462
+    complex<DP> Prod_powerN = 0.0;
463
+    complex<DP> Fn_K_1_G_2 = 0.0;
464
+    complex<DP> two_over_A_sinhlambda_sq_plus_sinzetaover2sq;
465
+    
466
+    
467
+    for (int j = 0; j < A.chain.Nstrings; ++j) {
468
+      for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
469
+	for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
470
+	  
471
+	  index_b = 0;
472
+	  
473
+	  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)
474
+								    + 0.25 * II * PI * (1.0 - A.chain.par[j]))) 
475
+							      * (sinh(A.lambda[j][alpha] + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)
476
+								      + 0.25 * II * PI * (1.0 - A.chain.par[j]))) 
477
+							      + pow(sin(0.5*A.chain.anis), 2.0));
478
+	  
479
+	  for (int k = 0; k < B.chain.Nstrings; ++k) {
480
+	    for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
481
+	      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
482
+		
483
+		if (B.chain.Str_L[k] == 1) {
484
+		  
485
+		  // use simplified code for one-string here:  original form of Hm2P matrix
486
+		  
487
+		  Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * 
488
+		    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);
489
+		  Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) *
490
+		    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);
491
+		  
492
+		  Prod_powerN = pow( B.chain.par[k] == 1 ? 
493
+				     (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])
494
+				     /(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])
495
+				     :
496
+				     (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])
497
+				     /(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])
498
+				     , complex<DP> (B.chain.Nsites));
499
+		  
500
+		  //cout << "Prod_powerN = " << Prod_powerN << "\t" << abs(Prod_powerN) << endl;
501
+		  
502
+		  Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2 - two_over_A_sinhlambda_sq_plus_sinzetaover2sq
503
+		    * exp(II*im_ln_Fn_F_B_0[k][beta] + logsinzeta);
504
+		  
505
+		}
506
+		
507
+		else {
508
+		  
509
+		  if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
510
+		  else if (b == B.chain.Str_L[k]) {
511
+		    
512
+		    Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
513
+		    for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
514
+		    
515
+		    Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
516
+		    for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
517
+		    
518
+		    sum1 = 0.0;
519
+		    
520
+		    sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
521
+		    
522
+		    sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) 
523
+		      * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] 
524
+			    - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
525
+		    
526
+		    for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) 
527
+		      
528
+		      sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
529
+			exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
530
+		    
531
+		    sum2 = 0.0;
532
+		    
533
+		    for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)  sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
534
+		    
535
+		    prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logsinzeta);
536
+		    
537
+		    for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)  
538
+		      prod_num *= exp(ln_FunctionG[jsum] - real(ln_FunctionF[jsum - 1]) + logsinzeta); 
539
+		    // include all string contributions F_B_0 in this term
540
+		    
541
+		    Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinhlambda_sq_plus_sinzetaover2sq);
542
+		    
543
+		  } // else if (b == B.chain.Str_L[k])
544
+		} // else 
545
+		
546
+		index_b++;
547
+	      }}} // sums over k, beta, b
548
+	  index_a++;
549
+	}}} // sums over j, alpha, a
550
+    
551
+    complex<DP> ln_det = lndet_LU_CX_dstry(Hm2P);
552
+    
553
+    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;
554
+    
555
+    //cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm 
556
+    //<< "\t" << re_ln_det << "\t" << ln_form_factor_sq << endl;
557
+    
558
+    //return(ln_ME_sq);
559
+    return(ln_ME); // Return ME, not MEsq
560
+    
561
+  }
562
+  
563
+} // namespace JSC

+ 304
- 0
src/HEIS/ln_Sz_ME_XXZ_gpd.cc View File

@@ -0,0 +1,304 @@
1
+#include "JSC.h"
2
+
3
+using namespace JSC;
4
+
5
+namespace JSC {
6
+
7
+inline complex<DP> ln_Fn_F (XXZ_gpd_Bethe_State& B, int k, int beta, int b)
8
+{
9
+  complex<DP> ans = 0.0;
10
+  complex<DP> prod_temp = 1.0;
11
+  int counter = 0;
12
+
13
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
14
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
15
+      for (int a = 1; a <= B.chain.Str_L[j]; ++a) {
16
+	/*
17
+	if (!((j == k) && (alpha == beta) && (a == b))) 
18
+	  ans += log(-II * sin(B.lambda[j][alpha] - B.lambda[k][beta]
19
+			    + 0.5 * II * B.chain.eta * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))));
20
+	*/
21
+
22
+	if (!((j == k) && (alpha == beta) && (a == b))) {
23
+
24
+	  //	  arg = B.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
25
+	  //	  absarg = abs(arg);
26
+	  
27
+	  prod_temp *= -II * (B.sinlambda[j][alpha] * B.coslambda[k][beta] - B.coslambda[j][alpha] * B.sinlambda[k][beta])
28
+	    * cosh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
29
+	    (B.coslambda[j][alpha] * B.coslambda[k][beta] + B.sinlambda[j][alpha] * B.sinlambda[k][beta]) 
30
+	    * sinh(0.5 * B.chain.anis * (B.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
31
+
32
+	}
33
+
34
+
35
+	if (counter++ > 10) {  // we do at most 10 products before taking a log
36
+	  ans += log(prod_temp);
37
+	  prod_temp = 1.0;
38
+	  counter = 0;
39
+	}
40
+
41
+      }}}
42
+
43
+  //  return(ans);
44
+  return(ans + log(prod_temp));
45
+}
46
+
47
+inline complex<DP> ln_Fn_G (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B, int k, int beta, int b)
48
+{
49
+  complex<DP> ans = 0.0;
50
+  complex<DP> prod_temp = 1.0;
51
+  int counter = 0;
52
+
53
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
54
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
55
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
56
+	/*
57
+	prod_temp *= -II * sin(A.lambda[j][alpha] - B.lambda[k][beta]
58
+		    + 0.5 * II * B.chain.eta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
59
+	*/
60
+
61
+	//	arg = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
62
+	//	absarg = abs(arg);
63
+
64
+	prod_temp *= -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
65
+	  * cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
66
+	  (A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
67
+	  * sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)));
68
+
69
+	if (counter++ > 25) {  // we do at most 25 products before taking a log
70
+	  ans += log(prod_temp);
71
+	  prod_temp = 1.0;
72
+	  counter = 0;
73
+	}
74
+      }}}
75
+
76
+  //  return(ans);
77
+  return(ans + log(prod_temp));
78
+}
79
+
80
+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)
81
+{
82
+  /*
83
+  return(-1.0/(sin(A.lambda[j][alpha] - B.lambda[k][beta]
84
+		    + 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) 
85
+	      * sin(A.lambda[j][alpha] - B.lambda[k][beta]
86
+		    + 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0)))));
87
+  */
88
+
89
+  //  int arg1 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b);
90
+  //  int absarg1 = abs(arg1);
91
+  //  int arg2 = A.chain.Str_L[j] - B.chain.Str_L[k] - 2 * (a - b - 1);
92
+  //  int arg2 = arg1 + 2;
93
+  //  int absarg2 = abs(arg2);
94
+
95
+  return(1.0/(( -II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
96
+	  * cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b))) +
97
+	  (A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
98
+	       * sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b)))) *
99
+	      (-II * (A.sinlambda[j][alpha] * B.coslambda[k][beta] - A.coslambda[j][alpha] * B.sinlambda[k][beta])
100
+	  * cosh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))) +
101
+	  (A.coslambda[j][alpha] * B.coslambda[k][beta] + A.sinlambda[j][alpha] * B.sinlambda[k][beta])
102
+	       * sinh(0.5 * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 1.0))))));
103
+
104
+}
105
+
106
+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)
107
+{
108
+  /*
109
+  complex<DP> ans = -II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
110
+				+ 0.5 * II * B.chain.zeta * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5)))); 
111
+
112
+  return (ans * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
113
+  */
114
+  return (-II * sin(2.0 * (A.lambda[j][alpha] - B.lambda[k][beta]
115
+		      + 0.5 * II * B.chain.anis * (A.chain.Str_L[j] - B.chain.Str_L[k] - 2.0 * (a - b - 0.5)))) 
116
+	  * pow(Fn_K (A, j, alpha, a, B, k, beta, b), 2.0));
117
+}
118
+
119
+complex<DP> ln_Sz_ME (XXZ_gpd_Bethe_State& A, XXZ_gpd_Bethe_State& B)
120
+{
121
+  // This function returns the natural log of the S^z operator matrix element.
122
+  // The A and B states can contain strings.
123
+
124
+  // Check that the two states refer to the same XXZ_gpd_Chain
125
+
126
+  if (A.chain != B.chain) JSCerror("Incompatible XXZ_gpd_Chains in Sz matrix element.");
127
+
128
+  // Check that A and B are compatible:  same Mdown
129
+
130
+  if (A.base.Mdown != B.base.Mdown) JSCerror("Incompatible Mdown between the two states in Sz matrix element!");
131
+
132
+  if (A.iK == B.iK && (A.label != B.label))
133
+    return(-300.0); // matrix element identically vanishes
134
+
135
+  // Compute the sin and cos of rapidities
136
+
137
+  A.Compute_sinlambda();
138
+  A.Compute_coslambda();
139
+  B.Compute_sinlambda();
140
+  B.Compute_coslambda();
141
+
142
+  // Some convenient arrays
143
+
144
+  Lambda re_ln_Fn_F_B_0(B.chain, B.base);
145
+  Lambda im_ln_Fn_F_B_0(B.chain, B.base);
146
+  Lambda re_ln_Fn_G_0(B.chain, B.base);
147
+  Lambda im_ln_Fn_G_0(B.chain, B.base);
148
+  Lambda re_ln_Fn_G_2(B.chain, B.base);
149
+  Lambda im_ln_Fn_G_2(B.chain, B.base);
150
+
151
+  complex<DP> ln_prod1 = 0.0;
152
+  complex<DP> ln_prod2 = 0.0;
153
+  complex<DP> ln_prod3 = 0.0;
154
+  complex<DP> ln_prod4 = 0.0;
155
+
156
+  for (int i = 0; i < A.chain.Nstrings; ++i) 
157
+    for (int alpha = 0; alpha < A.base.Nrap[i]; ++alpha)
158
+      for (int a = 1; a <= A.chain.Str_L[i]; ++a)
159
+	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))));
160
+
161
+  for (int i = 0; i < B.chain.Nstrings; ++i) 
162
+    for (int alpha = 0; alpha < B.base.Nrap[i]; ++alpha)
163
+      for (int a = 1; a <= B.chain.Str_L[i]; ++a)
164
+	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)
165
+	  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))));
166
+
167
+  // Define the F ones earlier...
168
+
169
+  for (int j = 0; j < B.chain.Nstrings; ++j) {
170
+    for (int alpha = 0; alpha < B.base.Nrap[j]; ++alpha) {
171
+      re_ln_Fn_F_B_0[j][alpha] = real(ln_Fn_F(B, j, alpha, 0));
172
+      im_ln_Fn_F_B_0[j][alpha] = imag(ln_Fn_F(B, j, alpha, 0));
173
+      re_ln_Fn_G_0[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 0));
174
+      im_ln_Fn_G_0[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 0));
175
+      re_ln_Fn_G_2[j][alpha] = real(ln_Fn_G(A, B, j, alpha, 2));
176
+      im_ln_Fn_G_2[j][alpha] = imag(ln_Fn_G(A, B, j, alpha, 2));
177
+    }
178
+  }
179
+
180
+  DP logabssinheta = log(abs(sinh(A.chain.anis)));
181
+
182
+  // Define regularized products in prefactors
183
+
184
+  for (int j = 0; j < A.chain.Nstrings; ++j)
185
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha)
186
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a)
187
+	ln_prod3 += ln_Fn_F(A, j, alpha, a - 1);  
188
+
189
+  ln_prod3 -= A.base.Mdown * log(abs(sinh(A.chain.anis)));
190
+
191
+  for (int k = 0; k < B.chain.Nstrings; ++k)
192
+    for (int beta = 0; beta < B.base.Nrap[k]; ++beta)
193
+      for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
194
+	if (b == 1) ln_prod4 += re_ln_Fn_F_B_0[k][beta];
195
+	else if (b > 1) ln_prod4 += ln_Fn_F(B, k, beta, b - 1);
196
+    }
197
+  
198
+  ln_prod4 -= B.base.Mdown * log(abs(sinh(B.chain.anis)));
199
+
200
+  // Now proceed to build the Hm2P matrix
201
+
202
+  SQMat_CX Hm2P(0.0, A.base.Mdown);
203
+
204
+  int index_a = 0;
205
+  int index_b = 0;
206
+
207
+  complex<DP> sum1 = 0.0;
208
+  complex<DP> sum2 = 0.0;
209
+  complex<DP> prod_num = 0.0;
210
+  complex<DP> Fn_K_0_G_0 = 0.0;
211
+  complex<DP> Prod_powerN = 0.0;
212
+  complex<DP> Fn_K_1_G_2 = 0.0;
213
+  complex<DP> two_over_A_sinlambda_sq_plus_sinhetaover2sq = 0.0;
214
+
215
+  for (int j = 0; j < A.chain.Nstrings; ++j) {
216
+    for (int alpha = 0; alpha < A.base.Nrap[j]; ++alpha) {
217
+      for (int a = 1; a <= A.chain.Str_L[j]; ++a) {
218
+	
219
+	index_b = 0;
220
+	
221
+	two_over_A_sinlambda_sq_plus_sinhetaover2sq = -2.0/((sin(A.lambda[j][alpha] // minus sign:  from 1/(sinh^2... to -1/(sin^2...
222
+								 + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a))) *  
223
+							    (sin(A.lambda[j][alpha] // minus sign:  from 1/(sinh^2... to -1/(sin^2...
224
+								 + 0.5 * II * A.chain.anis * (A.chain.Str_L[j] + 1.0 - 2.0 * a)))
225
+							   + pow(sinh(0.5*A.chain.anis), 2.0));
226
+
227
+	for (int k = 0; k < B.chain.Nstrings; ++k) {
228
+	  for (int beta = 0; beta < B.base.Nrap[k]; ++beta) {
229
+	    for (int b = 1; b <= B.chain.Str_L[k]; ++b) {
230
+
231
+	      if (B.chain.Str_L[k] == 1) {
232
+
233
+		// use simplified code for one-string here:  original form of Hm2P matrix
234
+
235
+		Fn_K_0_G_0 = Fn_K (A, j, alpha, a, B, k, beta, 0) * 
236
+		  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);
237
+		Fn_K_1_G_2 = Fn_K (A, j, alpha, a, B, k, beta, 1) * 
238
+		  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);
239
+
240
+		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])
241
+				  /(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]), 
242
+				  complex<DP> (B.chain.Nsites));
243
+
244
+		Hm2P[index_a][index_b] = Fn_K_0_G_0 - Prod_powerN * Fn_K_1_G_2 
245
+		  - two_over_A_sinlambda_sq_plus_sinhetaover2sq * exp(II*im_ln_Fn_F_B_0[k][beta] + logabssinheta);
246
+
247
+	      }
248
+	      
249
+	      else {
250
+
251
+		if (b <= B.chain.Str_L[k] - 1) Hm2P[index_a][index_b] = Fn_K(A, j, alpha, a, B, k, beta, b);
252
+		else if (b == B.chain.Str_L[k]) {
253
+		  
254
+		  Vect_CX ln_FunctionF(B.chain.Str_L[k] + 2);
255
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionF[i] = ln_Fn_F (B, k, beta, i);
256
+		  
257
+		  Vect_CX ln_FunctionG(B.chain.Str_L[k] + 2);
258
+		  for (int i = 0; i < B.chain.Str_L[k] + 2; ++i) ln_FunctionG[i] = ln_Fn_G (A, B, k, beta, i);
259
+		  
260
+		  sum1 = 0.0;
261
+		  
262
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, 0) * exp(ln_FunctionG[0] + ln_FunctionG[1] - ln_FunctionF[0] - ln_FunctionF[1]);
263
+		  
264
+		  sum1 += Fn_K (A, j, alpha, a, B, k, beta, B.chain.Str_L[k]) 
265
+		    * exp(ln_FunctionG[B.chain.Str_L[k]] + ln_FunctionG[B.chain.Str_L[k] + 1] 
266
+			  - ln_FunctionF[B.chain.Str_L[k]] - ln_FunctionF[B.chain.Str_L[k] + 1]);
267
+		  
268
+		  for (int jsum = 1; jsum < B.chain.Str_L[k]; ++jsum) 
269
+		    
270
+		    sum1 -= Fn_L (A, j, alpha, a, B, k, beta, jsum) *
271
+		      exp(ln_FunctionG[jsum] + ln_FunctionG[jsum + 1] - ln_FunctionF[jsum] - ln_FunctionF[jsum + 1]);
272
+		  
273
+		  sum2 = 0.0;
274
+		  
275
+		  for (int jsum = 1; jsum <= B.chain.Str_L[k]; ++jsum)  sum2 += exp(ln_FunctionG[jsum] - ln_FunctionF[jsum]);
276
+		  
277
+		  prod_num = exp(II * im_ln_Fn_F_B_0[k][beta] + ln_FunctionF[1] - ln_FunctionG[B.chain.Str_L[k]] + logabssinheta);
278
+
279
+		  for (int jsum = 2; jsum <= B.chain.Str_L[k]; ++jsum)  
280
+		    prod_num *= exp(ln_FunctionG[jsum] - real(ln_Fn_F(B, k, beta, jsum - 1)) + logabssinheta); 
281
+		  // include all string contributions F_B_0 in this term
282
+
283
+		  Hm2P[index_a][index_b] = prod_num * (sum1 - sum2 * two_over_A_sinlambda_sq_plus_sinhetaover2sq);
284
+
285
+		} // else if (b == B.chain.Str_L[k])
286
+	      } // else 
287
+
288
+	      index_b++;
289
+	    }}} // sums over k, beta, b
290
+	index_a++;
291
+      }}} // sums over j, alpha, a
292
+
293
+  complex<DP> ln_ME_sq = log(0.25 * A.chain.Nsites) + real(ln_prod1 - ln_prod2) - real(ln_prod3) + real(ln_prod4)
294
+    + 2.0 * real(lndet_LU_CX_dstry(Hm2P)) - A.lnnorm - B.lnnorm;
295
+
296
+  //cout << endl << ln_prod1 << "\t" << ln_prod2 << "\t" << ln_prod3 << "\t" << ln_prod4 << "\t" << A.lnnorm << "\t" << B.lnnorm << "\t" 
297
+  //   << lndet_LU_CX(Hm2P) << endl;
298
+  
299
+  //return(ln_ME_sq);
300
+  return(0.5 * ln_ME_sq); // Return ME, not MEsq
301
+
302
+}
303
+
304
+} // namespace JSC

+ 0
- 0
src/HEIS/ln_Szm_p_Smz_ME_XXX.cc View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save