HΦ  3.2.0
Lanczos_EigenVector.c
Go to the documentation of this file.
1 /* HPhi - Quantum Lattice Model Simulator */
2 /* Copyright (C) 2015 The University of Tokyo */
3 
4 /* This program is free software: you can redistribute it and/or modify */
5 /* it under the terms of the GNU General Public License as published by */
6 /* the Free Software Foundation, either version 3 of the License, or */
7 /* (at your option) any later version. */
8 
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU General Public License for more details. */
13 
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 
17 #include "Common.h"
18 #include "mltply.h"
19 #include "CalcTime.h"
20 #include "Lanczos_EigenVector.h"
21 #include "wrapperMPI.h"
22 
47 
50 
51  long int i,j,i_max,iv;
52  int k_exct, iproc;
53  double beta1,alpha1,dnorm, dnorm_inv;
54  double complex temp1,temp2,cdnorm;
55  int mythread;
56 
57 // for GC
58  long unsigned int u_long_i, sum_i_max, i_max_tmp;
59  dsfmt_t dsfmt;
60 
61  k_exct = X->Def.k_exct;
62 
63  iv=X->Large.iv;
64  i_max=X->Check.idim_max;
65 
66  if(initial_mode == 0){
67 
68  sum_i_max = SumMPI_li(X->Check.idim_max);
69  X->Large.iv = (sum_i_max / 2 + X->Def.initial_iv) % sum_i_max + 1;
70  iv=X->Large.iv;
71 #pragma omp parallel for default(none) private(i) shared(v0, v1,vg) firstprivate(i_max)
72  for(i = 1; i <= i_max; i++){
73  v0[i]=0.0;
74  v1[i]=0.0;
75  vg[i]=0.0;
76  }
77 
78  sum_i_max = 0;
79  for (iproc = 0; iproc < nproc; iproc++) {
80 
81  i_max_tmp = BcastMPI_li(iproc, i_max);
82  if (sum_i_max <= iv && iv < sum_i_max + i_max_tmp) {
83 
84  if (myrank == iproc) {
85  v1[iv - sum_i_max+1] = 1.0;
86  if (X->Def.iInitialVecType == 0) {
87  v1[iv - sum_i_max+1] += 1.0*I;
88  v1[iv - sum_i_max+1] /= sqrt(2.0);
89  }
90  vg[iv - sum_i_max+1]=conj(vec[k_exct][1])*v1[iv - sum_i_max+1];
91 
92  }/*if (myrank == iproc)*/
93  }/*if (sum_i_max <= iv && iv < sum_i_max + i_max_tmp)*/
94 
95  sum_i_max += i_max_tmp;
96 
97  }/*for (iproc = 0; iproc < nproc; iproc++)*/
98 
99  }/*if(initial_mode == 0)*/
100  else if(initial_mode==1){
101  iv = X->Def.initial_iv;
102  //fprintf(stdoutMPI, " initial_mode=%d (random): iv = %ld i_max=%ld k_exct =%d \n",initial_mode,iv,i_max,k_exct);
103  #pragma omp parallel default(none) private(i, u_long_i, mythread, dsfmt) \
104  shared(v0, v1, iv, X, nthreads, myrank) firstprivate(i_max)
105  {
106 
107 #pragma omp for
108  for (i = 1; i <= i_max; i++) {
109  v0[i] = 0.0;
110  }
111  /*
112  Initialize MT
113  */
114 #ifdef _OPENMP
115  mythread = omp_get_thread_num();
116 #else
117  mythread = 0;
118 #endif
119  u_long_i = 123432 + labs(iv) + mythread + nthreads * myrank;
120  dsfmt_init_gen_rand(&dsfmt, u_long_i);
121 
122  if (X->Def.iInitialVecType == 0) {
123 #pragma omp for
124  for (i = 1; i <= i_max; i++)
125  v1[i] = 2.0*(dsfmt_genrand_close_open(&dsfmt) - 0.5) + 2.0*(dsfmt_genrand_close_open(&dsfmt) - 0.5)*I;
126  }
127  else {
128 #pragma omp for
129  for (i = 1; i <= i_max; i++)
130  v1[i] = 2.0*(dsfmt_genrand_close_open(&dsfmt) - 0.5);
131  }
132  }/*#pragma omp parallel*/
133  /*
134  Normalize
135  */
136  cdnorm=0.0;
137 #pragma omp parallel for default(none) private(i) shared(v1, i_max) reduction(+: cdnorm)
138  for(i=1;i<=i_max;i++){
139  cdnorm += conj(v1[i])*v1[i];
140  }
141  cdnorm = SumMPI_dc(cdnorm);
142  dnorm=creal(cdnorm);
143  dnorm=sqrt(dnorm);
144 #pragma omp parallel for default(none) private(i) shared(v1, vec, vg) firstprivate(i_max, dnorm, k_exct)
145  for(i=1;i<=i_max;i++){
146  v1[i] = v1[i]/dnorm;
147  vg[i] = v1[i]*conj(vec[k_exct][1]);
148  }
149  }/*else if(initial_mode==1)*/
150  StartTimer(4201);
151  mltply(X, v0, v1);
152  StopTimer(4201);
153 
154  alpha1=alpha[1];
155  beta1=beta[1];
156 
157 #pragma omp parallel for default(none) private(j) shared(vec, v0, v1, vg) firstprivate(alpha1, beta1, i_max, k_exct)
158  for(j=1;j<=i_max;j++){
159  vg[j]+=conj(vec[k_exct][2])*(v0[j]-alpha1*v1[j])/beta1;
160  }
161 
162  //iteration
163  for(i=2;i<=X->Large.itr-1;i++) {
164  /*
165  if (abs(beta[i]) < pow(10.0, -15)) {
166  break;
167  }
168 */
169 #pragma omp parallel for default(none) private(j, temp1, temp2) shared(v0, v1) firstprivate(i_max, alpha1, beta1)
170  for (j = 1; j <= i_max; j++) {
171  temp1 = v1[j];
172  temp2 = (v0[j] - alpha1 * v1[j]) / beta1;
173  v0[j] = -beta1 * temp1;
174  v1[j] = temp2;
175  }
176  StartTimer(4201);
177  mltply(X, v0, v1);
178  StopTimer(4201);
179  alpha1 = alpha[i];
180  beta1 = beta[i];
181 #pragma omp parallel for default(none) private(j) shared(vec, v0, v1, vg) firstprivate(alpha1, beta1, i_max, k_exct, i)
182  for (j = 1; j <= i_max; j++) {
183  vg[j] += conj(vec[k_exct][i + 1]) * (v0[j] - alpha1 * v1[j]) / beta1;
184  }
185  }
186 
187 #pragma omp parallel for default(none) private(j) shared(v0, vg) firstprivate(i_max)
188  for(j=1;j<=i_max;j++){
189  v0[j] = vg[j];
190  }
191 
192  //normalization
193  dnorm=0.0;
194 #pragma omp parallel for default(none) reduction(+:dnorm) private(j) shared(v0) firstprivate(i_max)
195  for(j=1;j<=i_max;j++){
196  dnorm += conj(v0[j])*v0[j];
197  }
198  dnorm = SumMPI_d(dnorm);
199  dnorm=sqrt(dnorm);
200  dnorm_inv=1.0/dnorm;
201 #pragma omp parallel for default(none) private(j) shared(v0) firstprivate(i_max, dnorm_inv)
202  for(j=1;j<=i_max;j++){
203  v0[j] = v0[j]*dnorm_inv;
204  }
205 
207  fprintf(stdoutMPI, "%s", cLogLanczos_EigenVectorEnd);
208 }
struct DefineList Def
Definision of system (Hamiltonian) etc.
Definition: struct.h:410
int mltply(struct BindStruct *X, double complex *tmp_v0, double complex *tmp_v1)
Parent function of multiplying the wavefunction by the Hamiltonian. . First, the calculation of diago...
Definition: mltply.c:56
void StartTimer(int n)
function for initializing elapse time [start]
Definition: time.c:71
double complex SumMPI_dc(double complex norm)
MPI wrapper function to obtain sum of Double complex across processes.
Definition: wrapperMPI.c:205
int itr
Iteration number.
Definition: struct.h:315
unsigned long int idim_max
The dimension of the Hilbert space of this process.
Definition: struct.h:303
int initial_mode
Definition: global.h:60
unsigned long int BcastMPI_li(int root, unsigned long int idim)
MPI wrapper function to broadcast unsigned long integer across processes.
Definition: wrapperMPI.c:273
void StopTimer(int n)
function for calculating elapse time [elapse time=StartTimer-StopTimer]
Definition: time.c:83
double complex * v1
Definition: global.h:35
double complex ** vec
Definition: global.h:45
struct LargeList Large
Variables for Matrix-Vector product.
Definition: struct.h:412
double SumMPI_d(double norm)
MPI wrapper function to obtain sum of Double across processes.
Definition: wrapperMPI.c:222
int nthreads
Number of Threads, defined in InitializeMPI()
Definition: global.h:164
long int iv
Used for initializing vector.
Definition: struct.h:316
const char * cLogLanczos_EigenVectorStart
Definition: LogMessage.c:96
int nproc
Number of processors, defined in InitializeMPI()
Definition: global.h:162
Bind.
Definition: struct.h:409
const char * cLanczos_EigenVectorFinish
Definition: LogMessage.c:99
double * alpha
Definition: global.h:44
void Lanczos_EigenVector(struct BindStruct *X)
Calculate eigenvectors by the Lanczos method. The calculated tridiagonal matrix components are stor...
const char * cLanczos_EigenVectorStart
Definition: LogMessage.c:98
const char * cFileNameTimeKeep
Definition: global.c:23
double complex * vg
Definition: global.h:41
double * beta
Definition: global.h:44
struct EDMainCalStruct X
Definition: struct.h:432
long int initial_iv
Seed of random number for initial guesss of wavefunctions.
Definition: struct.h:76
int myrank
Process ID, defined in InitializeMPI()
Definition: global.h:163
int iInitialVecType
Switch for type of inital vectors. 0:complex type, 1: real type. default value is set as 0 in readdef...
Definition: struct.h:195
double complex * v0
Definition: global.h:34
struct CheckList Check
Size of the Hilbert space.
Definition: struct.h:411
unsigned long int SumMPI_li(unsigned long int idim)
MPI wrapper function to obtain sum of unsigned long integer across processes.
Definition: wrapperMPI.c:239
int TimeKeeper(struct BindStruct *X, const char *cFileName, const char *cTimeKeeper_Message, const char *cWriteType)
Functions for writing a time log.
Definition: log.c:42
const char * cLogLanczos_EigenVectorEnd
Definition: LogMessage.c:97
FILE * stdoutMPI
File pointer to the standard output defined in InitializeMPI()
Definition: global.h:165
unsigned int k_exct
Read from Calcmod in readdef.h.
Definition: struct.h:47