forked from chengchen1987/simple_ed_cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhmatrix_sparse.cpp
152 lines (142 loc) · 3.8 KB
/
hmatrix_sparse.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using namespace std;
#include <omp.h>
#include "hmatrix.h"
l_int Ham_1dXXZ::SparaseMat_Counts()
{
l_int counts = 0;
int L1 = LatticeSize - bc;
for (l_int k = 0; k < Dim; k++) {
l_int Num_k = basis->get_state(k);
// diagonal, always considered as non-zero
counts++;
// off-diagonal
for (int i = 0; i < LatticeSize - 1; i++)
{
int j = i + 1;
int k_i = ((Num_k >> i) & 1);
int k_j = ((Num_k >> j) & 1);
if (1 == k_i && 0 == k_j)
{
counts++;
}
}
if (0 == bc)
{
int i = LatticeSize - 1, j = 0;
int k_i = ((Num_k >> i) & 1);
int k_j = ((Num_k >> j) & 1);
if (0 == k_i && 1 == k_j)
{
counts++;
}
}
}
return counts;
}
// build sparse matrix of H
void Ham_1dXXZ::SparseMat_Build()
{
// get the number of nonzero elements
l_int nnz = SparaseMat_Counts();
SMat_vals = new double[nnz];
SMat_cols = new l_int[nnz];
SMat_PointerBE = new l_int[Dim + 1];
l_int counts = 0;
int L1 = LatticeSize - bc;
for (l_int k = 0; k < Dim; k++) {
l_int Num_k = basis->get_state(k);
// diagonal
double aux_diag = 0;
for (int i = 0; i < L1; i++)
{
int j = (i + 1) % LatticeSize;
int k_i = ((Num_k >> i) & 1);
int k_j = ((Num_k >> j) & 1);
aux_diag += (k_i ^ k_j) ? -0.25 * g : 0.25 * g;
}
SMat_vals[counts] = aux_diag;
SMat_cols[counts] = k;
SMat_PointerBE[k] = counts;
counts++;
// off-diagonal
vector <pair<l_int, double> > nonzero_pair;
for (int i = 0; i < LatticeSize - 1; i++)
{
int j = i + 1;
int k_i = ((Num_k >> i) & 1);
int k_j = ((Num_k >> j) & 1);
if (1 == k_i && 0 == k_j)
{
// then flip the states on i and j
l_int Num_l = Num_k ^ (1 << i) ^ (1 << j);
l_int state_l = basis->get_index(Num_l);
SMat_vals[counts] = 0.5;
SMat_cols[counts] = state_l;
counts++;
//pair<l_int, double> nonzero_aux = make_pair(state_l, 0.5);
//nonzero_pair.push_back(nonzero_aux);
}
}
if (0 == bc)
{
int i = LatticeSize - 1, j = 0;
int k_i = ((Num_k >> i) & 1);
int k_j = ((Num_k >> j) & 1);
if (0 == k_i && 1 == k_j)
{
// then flip the states on i and j
l_int Num_l = Num_k ^ (1 << i) ^ (1 << j);
l_int state_l = basis->get_index(Num_l);
SMat_vals[counts] = 0.5;
SMat_cols[counts] = state_l;
counts++;
//pair<l_int, double> nonzero_aux = make_pair(state_l, 0.5);
//nonzero_pair.push_back(nonzero_aux);
}
}
SMat_PointerBE[k + 1] = counts;
}
}
void Ham_1dXXZ::SparseMat_Eigs()
{
// 'V'/'I' with/without eigenvectors
char job_vec = 'V';
int M = 100;
if ('N' == job_vec)
{
double* l_vecs = new double[Dim];
rd_wf(Dim, l_vecs);
//uni_wf(Dim, l_vecs);
double* alpha = new double[M];
Lanczos(Dim, SMat_vals, SMat_cols, SMat_PointerBE, M, job_vec, alpha, l_vecs, NULL);
cout << "M = " << M << ", E[0] = " << setprecision(14) << alpha[0] << endl;
delete[]alpha;
delete[]l_vecs;
}
else if ('V' == job_vec)
{
double* l_vecs = new double[Dim * (M + 1)]; // Lanczos vectors
double* l_eigvecs = new double[M * M]; // eigenvectors in Lanczos basis
rd_wf(Dim, l_vecs);
//uni_wf(Dim, l_vecs);
double* alpha = new double[M];
Lanczos(Dim, SMat_vals, SMat_cols, SMat_PointerBE, M, job_vec, alpha, l_vecs, l_eigvecs);
cout << "M = " << M << ", E[0] = " << setprecision(14) << alpha[0] << endl;
delete[]alpha;
// groundstate wavefunction
double* wf0 = new double[Dim];
for (int i = 0; i < Dim; i++)
{
wf0[i] = cblas_ddot(M, &l_eigvecs[0], M, &l_vecs[i], Dim);
}
// check wf0
//cout << "<wf0|U[:,0]> = " << cblas_ddot(Dim, wf0, 1, &DMat[0], Dim) << endl;
delete[]wf0;
delete[]l_vecs;
}
else
{
cout << "Error! job_vec for Lanczos method must be either \'N\' or \'V\'!" << endl;
exit(666);
}
}