Skip to content

Commit e1f22ca

Browse files
committed
Adds preliminary ising/potts code
1 parent 6e2f1a4 commit e1f22ca

File tree

5 files changed

+292
-0
lines changed

5 files changed

+292
-0
lines changed

Diff for: ising/ising_action.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""
2+
Compute the Ising actions on cfgs in the given ensemble.
3+
"""
4+
5+
import argparse
6+
import numpy as np
7+
8+
def action(beta, cfg):
9+
assert(len(cfg.shape) == 2)
10+
return (beta * np.roll(cfg, -1, axis=0) * cfg +
11+
beta * np.roll(cfg, -1, axis=1) * cfg)
12+
13+
if __name__ == "__main__":
14+
parser = argparse.ArgumentParser(
15+
description='Compute Ising actions on cfgs in the given ensemble.')
16+
parser.add_argument('--tag', type=str, required=True)
17+
parser.add_argument('--Ncfg', type=int, required=True)
18+
parser.add_argument('--Lx', type=int, required=True)
19+
parser.add_argument('--Lt', type=int, required=True)
20+
parser.add_argument('--beta', type=float, required=True)
21+
args = parser.parse_args()
22+
fname = args.tag + '.dat'
23+
cfgs = np.fromfile(fname, dtype=np.float64).reshape(
24+
args.Ncfg, args.Lx, args.Lt)
25+
actions = []
26+
for c in cfgs:
27+
S = np.sum(action(args.beta, c))
28+
print('S = {}'.format(S))
29+
actions.append(S)
30+
fname = args.tag + '.S.dat'
31+
np.array(actions).tofile(fname)
32+
print('Wrote actions to {}.'.format(fname))

Diff for: ising/ising_corr.py

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"""
2+
Compute correlators for 2D Ising model.
3+
"""
4+
5+
import argparse
6+
import numpy as np
7+
import time
8+
import tqdm
9+
10+
def compute_twopt_vev(c, alpha, beta):
11+
alpha_term = alpha * np.sum(c, axis=0)
12+
beta_term = beta * np.sum(
13+
c * np.roll(c, -1, axis=0) * np.roll(c, -2, axis=0), axis=0)
14+
op = alpha_term + beta_term
15+
assert(len(op.shape) == 1) # projected to just time
16+
Lt = op.shape[0]
17+
twopt = np.zeros((Lt,), dtype=np.float64)
18+
for dt in range(Lt):
19+
twopt[dt] = np.sum(op * np.roll(op, -dt, axis=0)) / Lt
20+
return twopt, op
21+
22+
if __name__ == "__main__":
23+
parser = argparse.ArgumentParser(
24+
description='Compute 2D Ising corrs on ensemble.')
25+
parser.add_argument('--tag', type=str, required=True)
26+
parser.add_argument('--Ncfg', type=int, required=True)
27+
parser.add_argument('--Lx', type=int, required=True)
28+
parser.add_argument('--Lt', type=int, required=True)
29+
parser.add_argument('--alpha', type=float, required=True,
30+
help='One sigma coeff.')
31+
parser.add_argument('--beta', type=float, required=True,
32+
help='Three sigma coeff.')
33+
args = parser.parse_args()
34+
print('Running with args = {}'.format(args))
35+
36+
fname = args.tag + '.dat'
37+
print('Reading ensemble from {}'.format(fname))
38+
cfgs = np.fromfile(fname, dtype=np.float64).reshape(
39+
args.Ncfg, args.Lx, args.Lt)
40+
twopts = []
41+
vevs = []
42+
start = time.time()
43+
for c in tqdm.tqdm(cfgs):
44+
twopt, vev = compute_twopt_vev(c, args.alpha, args.beta)
45+
twopts.append(twopt)
46+
vevs.append(vev)
47+
twopts = np.array(twopts)
48+
vevs = np.array(vevs)
49+
print('Done all corrs in {:.1f}s'.format(time.time() - start))
50+
print('twopts shape = {}'.format(twopts.shape))
51+
print('vevs shape = {}'.format(vevs.shape))
52+
fname = args.tag + '.twopt_a{:.2f}_b{:.2f}.dat'.format(args.alpha, args.beta)
53+
twopts.tofile(fname)
54+
print('Wrote twopts to {}.'.format(fname))
55+
fname = args.tag + '.vev_a{:.2f}_b{:.2f}.dat'.format(args.alpha, args.beta)
56+
vevs.tofile(fname)
57+
print('Wrote vevs to {}.'.format(fname))

Diff for: ising/potts_action.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""
2+
Compute the Potts actions on cfgs in the given ensemble.
3+
"""
4+
5+
import argparse
6+
import numpy as np
7+
8+
# Action is normalized/shifted to equal Ising for identical beta.
9+
def action(beta, cfg):
10+
assert(len(cfg.shape) == 2)
11+
return (beta * (2*(np.roll(cfg, -1, axis=0) == cfg)-1) +
12+
beta * (2*(np.roll(cfg, -1, axis=1) == cfg)-1))
13+
14+
if __name__ == "__main__":
15+
parser = argparse.ArgumentParser(
16+
description='Compute Potts actions on cfgs in the given ensemble.')
17+
parser.add_argument('--tag', type=str, required=True)
18+
parser.add_argument('--Ncfg', type=int, required=True)
19+
parser.add_argument('--Lx', type=int, required=True)
20+
parser.add_argument('--Lt', type=int, required=True)
21+
parser.add_argument('--beta', type=float, required=True)
22+
args = parser.parse_args()
23+
fname = args.tag + '.dat'
24+
cfgs = np.fromfile(fname, dtype=np.float64).reshape(
25+
args.Ncfg, args.Lx, args.Lt)
26+
actions = []
27+
for c in cfgs:
28+
S = np.sum(action(args.beta, c))
29+
print('S = {}'.format(S))
30+
actions.append(S)
31+
fname = args.tag + '.S.dat'
32+
np.array(actions).tofile(fname)
33+
print('Wrote actions to {}.'.format(fname))

Diff for: ising/potts_corr.py

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
"""
2+
Compute correlators for 2D Potts model (either directly or random cluster).
3+
"""
4+
5+
from cftp import *
6+
7+
import argparse
8+
import math
9+
import networkx as nx
10+
import numpy as np
11+
import time
12+
import tqdm
13+
14+
def compute_twopt(c, use_extra_ops):
15+
op = np.sum(c, axis=0)
16+
assert(len(op.shape) == 1) # projected to just time
17+
Lt = op.shape[0]
18+
ops = [np.ones((Lt,), dtype=np.complex128), op]
19+
# twopt = np.zeros((Lt,), dtype=np.complex128)
20+
# for dt in range(Lt):
21+
# twopt[dt] = np.sum(np.conj(op) * np.roll(op, -dt, axis=0)) / Lt
22+
# return twopt, op
23+
if use_extra_ops:
24+
# (sigma_z^x)^2 = (sigma_z^x)^*
25+
ops.append(np.sum(np.conj(c), axis=0))
26+
# sigma_z^x (sigma_z^(x+1))^*
27+
ops.append(np.sum(c * np.roll(np.conj(c), -1, axis=0), axis=0))
28+
# (sigma_z^x)^* sigma_z^(x+1)
29+
ops.append(np.sum(np.conj(c) * np.roll(c, -1, axis=0), axis=0))
30+
# sigma_z^x (sigma_z^(x+2))^*
31+
ops.append(np.sum(c * np.roll(np.conj(c), -2, axis=0), axis=0))
32+
# (sigma_z^x)^* sigma_z^(x+2)
33+
ops.append(np.sum(np.conj(c) * np.roll(c, -2, axis=0), axis=0))
34+
# sigma_z^x sigma_z^(x+1)
35+
ops.append(np.sum(c * np.roll(c, -1, axis=0), axis=0))
36+
# (sigma_z^x)^* (sigma_z^(x+1))^*
37+
ops.append(np.sum(np.conj(c * np.roll(c, -1, axis=0)), axis=0))
38+
39+
N_ops = len(ops)
40+
twopt = np.zeros((Lt,N_ops,N_ops), dtype=np.complex128)
41+
for dt in range(Lt):
42+
for src,src_op in enumerate(ops):
43+
for snk,snk_op in enumerate(ops):
44+
twopt[dt,src,snk] = np.sum(np.conj(src_op) * np.roll(snk_op, -dt, axis=0)) / Lt
45+
return twopt
46+
47+
def compute_twopt_cluster(c_and_mag):
48+
c = c_and_mag[:2]
49+
mag = c_and_mag[2]
50+
Lt = c.shape[-1]
51+
g = make_cluster_graph(c)
52+
g = extend_graph_with_ghost(g, mag)
53+
comps = nx.connected_components(g)
54+
twopt = np.zeros((Lt,), dtype=np.complex128)
55+
mag_count = 0
56+
for comp in comps:
57+
counts = np.zeros((Lt,), dtype=np.complex128)
58+
ghost_comp = 'ghost' in comp
59+
for x in comp:
60+
if x == 'ghost': continue
61+
counts[x[-1]] += 1
62+
if ghost_comp: mag_count += 1
63+
for dt in range(Lt):
64+
twopt[dt] += np.sum(counts * np.roll(counts, -dt, axis=0)) / Lt
65+
vev = mag_count/Lt
66+
return twopt, vev
67+
68+
if __name__ == "__main__":
69+
parser = argparse.ArgumentParser(
70+
description='Compute 2D Potts corrs on ensemble.')
71+
parser.add_argument('--tag', type=str, required=True)
72+
parser.add_argument('--Ncfg', type=int, required=True)
73+
parser.add_argument('--n_state', type=int, required=True)
74+
parser.add_argument('--Lx', type=int, required=True)
75+
parser.add_argument('--Lt', type=int, required=True)
76+
parser.add_argument('--use_clusters', action='store_true')
77+
parser.add_argument('--use_extra_ops', action='store_true')
78+
args = parser.parse_args()
79+
print('Running with args = {}'.format(args))
80+
81+
if args.use_clusters:
82+
fname = args.tag + '.cluster.dat'
83+
print('Reading cluster ensemble from {}'.format(fname))
84+
cfgs = np.fromfile(fname, dtype=np.float64).reshape(
85+
args.Ncfg, 2+1, args.Lx, args.Lt)
86+
else:
87+
fname = args.tag + '.dat'
88+
print('Reading ensemble from {}'.format(fname))
89+
cfgs = np.fromfile(fname, dtype=np.float64).reshape(
90+
args.Ncfg, args.Lx, args.Lt)
91+
cfgs = np.exp(2j * math.pi * cfgs / args.n_state)
92+
twopts = []
93+
vevs = []
94+
start = time.time()
95+
for c in tqdm.tqdm(cfgs):
96+
if args.use_clusters:
97+
twopt,vev = compute_twopt_cluster(c)
98+
vevs.append(vev)
99+
else:
100+
twopt = compute_twopt(c, args.use_extra_ops)
101+
twopts.append(twopt)
102+
twopts = np.array(twopts)
103+
vevs = np.array(vevs)
104+
print('Done all corrs in {:.1f}s'.format(time.time() - start))
105+
print('twopts shape = {}'.format(twopts.shape))
106+
print('vevs shape = {}'.format(vevs.shape))
107+
if args.use_clusters:
108+
fname = args.tag + '.twopt_clusters.dat'
109+
else:
110+
fname = args.tag + '.twopt.dat'
111+
twopts.tofile(fname)
112+
print('Wrote twopts to {}.'.format(fname))
113+
if args.use_clusters:
114+
fname = args.tag + '.vev_clusters.dat'
115+
else:
116+
fname = args.tag + '.vev.dat'
117+
vevs.tofile(fname)
118+
print('Wrote vevs to {}.'.format(fname))

Diff for: ising/potts_sample_cluster.py

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""
2+
Sample clusters for 2D Potts model.
3+
"""
4+
5+
from cftp import *
6+
7+
import argparse
8+
import networkx as nx
9+
import numpy as np
10+
import time
11+
import tqdm
12+
13+
if __name__ == "__main__":
14+
parser = argparse.ArgumentParser(
15+
description='Sample potts cfgs from clusters.')
16+
parser.add_argument('--tag', type=str, required=True)
17+
parser.add_argument('--Ncfg', type=int, required=True)
18+
parser.add_argument('--n_state', type=int, required=True)
19+
parser.add_argument('--Lx', type=int, required=True)
20+
parser.add_argument('--Lt', type=int, required=True)
21+
args = parser.parse_args()
22+
print('Running with args = {}'.format(args))
23+
24+
fname = args.tag + '.cluster.dat'
25+
print('Reading cluster ensemble from {}'.format(fname))
26+
cfgs = np.fromfile(fname, dtype=np.float64).reshape(
27+
args.Ncfg, 2+1, args.Lx, args.Lt)
28+
29+
L = (args.Lx, args.Lt)
30+
spin_cfgs = []
31+
start = time.time()
32+
for c_and_mag in tqdm.tqdm(cfgs):
33+
c = c_and_mag[:2]
34+
mag = c_and_mag[2]
35+
g = make_cluster_graph(c)
36+
g = extend_graph_with_ghost(g, mag)
37+
comps = nx.connected_components(g)
38+
spin_cfg = np.zeros(L)
39+
for comp in comps:
40+
if 'ghost' in comp:
41+
val = 0
42+
else:
43+
val = np.random.choice(np.arange(args.n_state))
44+
for x in comp:
45+
if x == 'ghost': continue
46+
spin_cfg[x] = val
47+
spin_cfgs.append(spin_cfg)
48+
print('Potts resampling complete!')
49+
print('Total time = {:.1f}s'.format(time.time() - start))
50+
fname = args.tag + '.dat'
51+
np.array(spin_cfgs).tofile(fname)
52+
print('Wrote Potts spin cfgs to file {}'.format(fname))

0 commit comments

Comments
 (0)