StatMech
Loading...
Searching...
No Matches
generateRM.hpp
Go to the documentation of this file.
1// Generate a random matrix used by all programs in this directory
2#ifndef GENERATE_RM
3#define GENERATE_RM
4#define _USE_MATH_DEFINES
5
6#include "Headers/mytypes.hpp"
7#include "Headers/LocalRandomMatrix.hpp"
8#include "Headers/matrix_util.hpp"
9#include "Headers/spin_int.hpp"
10#include "Headers/mersenne_twister.hpp"
11#include "Headers/mydebug.hpp"
12#include <iostream>
13#include <cassert>
14#include <sysexits.h>
15#include <cmath>
16
17#define RANDTYPE argv[Nargs_common+0] << argv[Nargs_common+1] << "H_" << argv[Nargs_common+2] << argv[Nargs_common+3] << "Op"
18#define USAGE_sp "sp1.(Decay type of H) sp2.(Decay parameter for H) sp3.(Decay type of Op) sp4.(Decay parameter for Op) "
19#define Nargs_sp 4
20
21static inline double Prefactor(Integer_t const j, std::string const Type, double const param) {
22 if(Type == "Exp") return exp( -(j-1)*param );
23 else if(Type == "Pow") return pow(j,-param);
24 else if(Type == "Short") return (j==1 ? 1: 0);
25 else if(Type == "Full") return 1;
26 else if(Type == "CRMT") return NAN;
27 else {
28 std::cerr << "Usage: Decay type (argument 7) must be either \"Exp\", \"Pow\", \"Short\", \"Full\", or \"CRMT\"." << std::endl;
29 std::exit(EX_USAGE);
30 }
31}
32
33std::vector<std::vector<double>> prefactorH;
34std::vector<std::vector<double>> prefactorOp;
35static inline bool Initialize(int const argc, char const*const* argv, int const Nargs_common) {
36 Integer_t const n_max = (Integer_t)std::atoll(argv[1]);
37 Integer_t const n_min = (Integer_t)std::atoll(argv[2]);
38 std::string const TypeH(argv[Nargs_common+0]);
39 double const paramH = atof(argv[Nargs_common+1]);
40 std::string const TypeOp(argv[Nargs_common+2]);
41 double const paramOp = atof(argv[Nargs_common+3]);
42
43 prefactorH.resize(n_max+1); prefactorOp.resize(n_max+1);
44 for(Integer_t n = n_min;n <= n_max; ++n) {
45 prefactorH[n].resize(n); prefactorH[n][0] = 0;
46 prefactorOp[n].resize(n); prefactorOp[n][0] = 0;
47 for(Integer_t j = 1;j <= n/2; ++j) {
48 prefactorH[n][j] = Prefactor(j, TypeH, paramH);
49 prefactorOp[n][j] = Prefactor(j, TypeOp, paramOp);
50 prefactorH[n].at(n-j) = prefactorH[n][j];
51 prefactorOp[n].at(n-j) = prefactorOp[n][j];
52 }
53 std::cout << "# Decay factor for Hamiltonians." << std::endl;
54 print(prefactorH[n], n);
55 std::cout << "# Decay factor for observables." << std::endl;
56 print(prefactorOp[n], n);
57 }
58 return true;
59}
60static inline bool Finalize(int const argc, char const*const* argv) { return true; }
61
62static inline Integer_t SectorDimension(TransSector const& Sector) {
63 return (Sector.momentum()==0) ? Sector.dim()-Sector.parityOp().numPairs : Sector.dim();
64}
65
66static inline void generateLocal_h(matrix<Complex_t>& mat, Integer_t const d_lmat, Integer_t const seed){
67 if(seed >= 0) {
68 init_genrand(seed);
69 std::cout << "# init_genrand(" << seed << ")\n";
70 }
71 RandomMatrix_GUE(mat, d_lmat);
72};
73static inline void generateLocal_op(matrix<Complex_t>& mat, Integer_t const d_lmat, Integer_t const seed){
74 if(seed >= 0) init_genrand(seed);
75 generateLocal_h(mat, d_lmat, seed);
76};
77
78static inline void MatrixElementsInSector(matrix<Complex_t>& matTot, matrix<Complex_t> const& matLoc, Integer_t const numLoc, TransSector const& Sector, std::vector<double> const& factor);
79
80static inline Integer_t constructGlobalOperator(matrix<Complex_t>& global, matrix<Complex_t> const& local, Integer_t const numLoc, TransSector const& Sector, std::vector<double> const& factor, void* GPUconf = nullptr) {
81 MatrixElementsInSector(global, local, numLoc, Sector, factor);
82 return SectorDimension(Sector);
83}
84static inline Integer_t constructGlobal_h(matrix<Complex_t>& global, matrix<Complex_t> const& local, Integer_t const numLoc, TransSector const& Sector, void* GPUconf = nullptr){
85 return constructGlobalOperator(global, local, numLoc, Sector, prefactorH[Sector.N()]);
86
87 #ifndef NDEBUG
88 if(Sector.N() <= 4) {
89 Integer_t d_loch = pow(Sector.dloc(), numLoc);
90 std::cout << "n=" << Sector.N() << "\n";
91 local.print(d_loch,d_loch);
92 global.print(Sector.dim(),Sector.dim());
93 std::cout << "\n" << std::endl;
94 }
95 #endif
96};
97
98static inline Integer_t constructGlobal_op(matrix<Complex_t>& global, matrix<Complex_t> const& local, Integer_t const numLoc, TransSector const& Sector, void* GPUconf = nullptr){
99 return constructGlobalOperator(global, local, numLoc, Sector, prefactorOp[Sector.N()]);
100};
101
102static inline Complex_t transEigenMatrixElements(Integer_t const idx, Integer_t const idy, matrix<Complex_t> const& matLoc, TransSector const& Sector, std::vector<double> const& factor) {
103 Integer_t trans1, trans2;
104 Integer_t Id1, Id2, locId1, locId2;
105 Integer_t Ndiff, diff, pos;
106 double theta;
107
108 Complex_t res = ComplexZero<>;
109 for(trans1 = 0;trans1 < Sector.periodicity(idx); ++trans1) {
110 Id1 = transSpin(Sector.representative(idx),trans1,Sector.dloc(),Sector.N());
111 for(trans2 = 0;trans2 < Sector.periodicity(idy); ++trans2) {
112 Id2 = transSpin(Sector.representative(idy),trans2,Sector.dloc(),Sector.N());
113 theta = 2.0*M_PI*Sector.momentum()*(trans2-trans1)/(Real_t)Sector.N();
114 Ndiff = 0;
115 for(pos = 1;pos<Sector.N() && Ndiff<2; ++pos) {
116 if( Bit(Id1,pos,Sector.dloc(),Sector.N())!=Bit(Id2,pos,Sector.dloc(),Sector.N()) ) { Ndiff+=1; diff=pos; }
117 }
118 switch(Ndiff){
119 case 0:
120 for(diff = 1;diff < Sector.N(); ++diff) {
121 locId1 = Bit(Id1,0,Sector.dloc(),Sector.N()) + Sector.dloc()*Bit(Id1,diff,Sector.dloc(),Sector.N());
122 locId2 = Bit(Id2,0,Sector.dloc(),Sector.N()) + Sector.dloc()*Bit(Id2,diff,Sector.dloc(),Sector.N());
123 res += factor.at(diff)*matLoc.at(locId1,locId2)*std::exp(I<>*theta);
124 }
125 break;
126 case 1:
127 locId1 = Bit(Id1,0,Sector.dloc(),Sector.N()) + Sector.dloc()*Bit(Id1,diff,Sector.dloc(),Sector.N());
128 locId2 = Bit(Id2,0,Sector.dloc(),Sector.N()) + Sector.dloc()*Bit(Id2,diff,Sector.dloc(),Sector.N());
129 res += factor.at(diff)*matLoc.at(locId1,locId2)*std::exp(I<>*theta);
130 break;
131 default:
132 continue;
133 }
134 }
135 }
136
137 res /= sqrt( (double)Sector.periodicity(idx)*Sector.periodicity(idy) );
138 return res;
139}
140
141static inline void MatrixElementsInSector(matrix<Complex_t>& matTot, matrix<Complex_t> const& matLoc, Integer_t const numLoc, TransSector const& Sector, std::vector<double> const& factor) {
142 Integer_t const dim = (Sector.momentum() == 0) ? (Sector.dim()-Sector.parityOp().numPairs): Sector.dim();
143 Integer_t const numParityEigens = (Sector.momentum() == 0) ? (Sector.dim()-2*Sector.parityOp().numPairs) : Sector.dim();
144 debug_print("# MatrixElementsInSector: N=" << Sector.N() << ", dim=" << dim);
145 std::fill(matTot.begin(), matTot.end(), ComplexZero<>);
146
147 Complex_t tempMatElem1, tempMatElem2;
148
149 #pragma omp parallel for schedule(dynamic, 1) private(tempMatElem1, tempMatElem2)
150 for(int idx = 0;idx < numParityEigens; ++idx) {
151 for(int idy = idx;idy < numParityEigens; ++idy) {
152 matTot.at(idx,idy) = transEigenMatrixElements(idx, idy, matLoc, Sector, factor);
153 matTot.at(idy,idx) = conj(matTot.at(idx,idy));
154 }
155 for(int idy = numParityEigens;idy < dim; ++idy) {
156 tempMatElem1 = transEigenMatrixElements(idx, idy, matLoc, Sector, factor);
157 tempMatElem2 = transEigenMatrixElements(idx, Sector.parityOp(idy), matLoc, Sector, factor);
158 matTot.at(idx,idy) = (tempMatElem1 + tempMatElem2)/sqrt(2.0);
159 matTot.at(idy,idx) = conj(matTot.at(idx,idy));
160 }
161 }
162
163 #pragma omp parallel for schedule(dynamic, 1) private(tempMatElem1, tempMatElem2)
164 for(int idx = numParityEigens;idx < dim; ++idx) {
165 for(int idy = idx;idy < dim; ++idy) {
166 tempMatElem1 = transEigenMatrixElements(idx, idy, matLoc, Sector, factor);
167 tempMatElem2 = transEigenMatrixElements(idx, Sector.parityOp(idy), matLoc, Sector, factor);
168 matTot.at(idx,idy) = tempMatElem1 + tempMatElem2;
169 matTot.at(idy,idx) = conj(matTot.at(idx,idy));
170 }
171 }
172
173 #pragma omp parallel for schedule(dynamic, 1) private(tempMatElem1, tempMatElem2)
174 for(int idx = 0;idx < dim; ++idx) matTot.at(idx,idx) = ComplexOne<>*real(matTot.at(idx,idx));
175}
176
177#endif
__global__ void MatrixElementsInSector(void)
Definition generateRM.cuh:61
__device__ Complex_t transEigenMatrixElements(Integer_t const idx, Integer_t const idy, Complex_t const *__restrict__ dmatLoc, Integer_t const LDL, Integer_t const n, Integer_t const dloc, Integer_t const momentum, Integer_t const *representatives, Integer_t const *periodicity, Real_t const *__restrict__ dfactor)
Definition generateRM.cuh:141
std::vector< std::vector< double > > prefactorOp
Definition generateRM.hpp:34
std::vector< std::vector< double > > prefactorH
Definition generateRM.hpp:33
std::vector< TransSector > Sector(n_max+1)
Definition mytypes.hpp:147
Translation invariant sector of a many-body Hilbert space.
Definition TransSector.hpp:19
debug_print("# Determining GPU configuration.")
GPUconfig GPUconf(dim3(nBlock, nBlock, 1), dim3(nThread, nThread, 1), 0, queue)
double Real_t
Definition mytypes.hpp:37
MKL_INT Integer_t
Definition mytypes.hpp:359
Integer_t const n_min
Definition setVariablesForEnsemble.cpp:28
Integer_t const n_max
Definition setVariablesForEnsemble.cpp:27