Skip to content

Commit f95394e

Browse files
committed
exercise 5
1 parent b12b432 commit f95394e

File tree

3 files changed

+597
-0
lines changed

3 files changed

+597
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"""Exact diagonalization code for the transverse field Ising model with momentum conservation.
2+
3+
H = -J sum_i sigma^x_i sigma^x_{i+1} - g sum_i sigma^z i; periodic boundary cond.
4+
5+
"""
6+
7+
import numpy as np
8+
import scipy.sparse.linalg
9+
import matplotlib.pyplot as plt
10+
11+
12+
def flip(s, i, N):
13+
"""Flip the bits of the state `s` at positions i and (i+1)%N."""
14+
return s ^ (1 << i | 1 << ((i+1) % N))
15+
16+
17+
def translate(s, N):
18+
"""Shift the bits of the state `s` one position to the right (cyclically for N bits)."""
19+
bs = bin(s)[2:].zfill(N)
20+
return int(bs[-1] + bs[:-1], base=2)
21+
22+
23+
def count_ones(s, N):
24+
"""Count the number of `1` in the binary representation of the state `s`."""
25+
return bin(s).count('1')
26+
27+
28+
def is_representative(s, k, N):
29+
"""Check if |s> is the representative for the momentum state.
30+
31+
Returns -1 if s is not a representative.
32+
If |s> is a representative, return the periodicity R,
33+
i.e. the smallest integer R > 0 such that T**R |s> = |s>."""
34+
t = s
35+
for i in range(N):
36+
t = translate(t, N)
37+
if t < s:
38+
return -1 # there is a smaller representative in the orbit
39+
elif (t == s):
40+
if (np.mod(k, N/(i+1)) != 0):
41+
return -1 # periodicty incompatible with k
42+
else:
43+
return i+1
44+
45+
46+
def get_representative(s, N):
47+
"""Find the representative r in the orbit of s and return (r, l) such that |r>= T**l|s>"""
48+
r = s
49+
t = s
50+
l = 0
51+
for i in range(N):
52+
t = translate(t, N)
53+
if (t < r):
54+
r = t
55+
l = i + 1
56+
return r, l
57+
58+
59+
def calc_basis(N):
60+
"""Determine the (representatives of the) basis for each block.
61+
62+
A block is detemined by the quantum numbers `qn`, here simply `k`.
63+
`basis` and `ind_in_basis` are dictionaries with `qn` as keys.
64+
For each block, `basis[qn]` contains all the representative spin configurations `sa`
65+
and periodicities `Ra` generating the state
66+
``|a(k)> = 1/sqrt(Na) sum_l=0^{N-1} exp(i k l) T**l |sa>``
67+
68+
`ind_in_basis[qn]` is a dictionary mapping from the representative spin configuration `sa`
69+
to the index within the list `basis[qn]`.
70+
"""
71+
basis = dict()
72+
ind_in_basis = dict()
73+
for sa in range(2**N):
74+
for k in range(-N//2+1, N//2+1):
75+
qn = k
76+
Ra = is_representative(sa, k, N)
77+
if Ra > 0:
78+
if qn not in basis:
79+
basis[qn] = []
80+
ind_in_basis[qn] = dict()
81+
ind_in_basis[qn][sa] = len(basis[qn])
82+
basis[qn].append((sa, Ra))
83+
return basis, ind_in_basis
84+
85+
86+
def calc_H(N, J, g):
87+
"""Determine the blocks of the Hamiltonian as scipy.sparse.csr_matrix."""
88+
print("Generating Hamiltonian ... ", end="", flush=True)
89+
basis, ind_in_basis = calc_basis(N)
90+
H = {}
91+
for qn in basis:
92+
M = len(basis[qn])
93+
H_block_data = []
94+
H_block_inds = []
95+
a = 0
96+
for sa, Ra in basis[qn]:
97+
H_block_data.append(-g * (-N + 2*count_ones(sa, N)))
98+
H_block_inds.append((a, a))
99+
for i in range(N):
100+
sb, l = get_representative(flip(sa, i, N), N)
101+
if sb in ind_in_basis[qn]:
102+
b = ind_in_basis[qn][sb]
103+
Rb = basis[qn][b][1]
104+
k = qn*2*np.pi/Ra
105+
H_block_data.append(-J*np.exp(-1j*k*l)*np.sqrt(Ra/Rb))
106+
H_block_inds.append((b, a))
107+
# else: flipped state incompatible with the k value, |b(k)> is zero
108+
a += 1
109+
H_block_inds = np.array(H_block_inds)
110+
H_block_data = np.array(H_block_data)
111+
H_block = scipy.sparse.csr_matrix((H_block_data, (H_block_inds[:, 0], H_block_inds[:, 1])),
112+
shape=(M,M),dtype=np.complex)
113+
H[qn] = H_block
114+
print("done", flush=True)
115+
return H

2_exact_diagonalization/hw05.pdf

124 KB
Binary file not shown.

0 commit comments

Comments
 (0)