Skip to content

Commit

Permalink
update cftp code fix hexagon bug
Browse files Browse the repository at this point in the history
  • Loading branch information
neozhaoliang committed Jan 17, 2024
1 parent 5075885 commit fc7cdf8
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 65 deletions.
94 changes: 49 additions & 45 deletions src/cftp/cftp/lozenge_tiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@


class LozengeTiling(MonotoneMarkovChain):

r"""
This class builds the "monotone" Markov chain structure on the set
of lozenge tilings of an (a x b x c) hexagon. A tiling is represented
Expand All @@ -29,7 +28,7 @@ class LozengeTiling(MonotoneMarkovChain):
| |
O\ |
\ /
\____/
\____/
\
+x (-30 deg)
Expand Down Expand Up @@ -63,7 +62,10 @@ def min_max_states(self):
for k in range(c + 2)
]
s1 = [
[c + 1 + min(j, b) if k == c + 1 else k + max(j - a, 0) for j in range(a + b + 1)]
[
c + 1 + min(j, b) if k == c + 1 else k + max(j - a, 0)
for j in range(a + b + 1)
]
for k in range(c + 2)
]
return s0, s1
Expand All @@ -86,8 +88,7 @@ def new_random_update(self):
) # a random direction (up or down)

def update(self, state, operation):
"""Update a state by a random update operation.
"""
"""Update a state by a random update operation."""
s = state
k, j, dy = operation
# try to push up
Expand All @@ -109,47 +110,50 @@ def get_tiles(self, state):
verts = {"L": [], "R": [], "T": []}
for k in range(c + 1): # loop over the paths from bottom to top
for j in range(1, a + b + 1): # loop over the inner sites
if k > 0:
if s[k][j] == s[k][j - 1]:
# (-1, 0)
# |\
# | \ (0, 0)
# (-1, -1) | |
# \ |
# \|
# (0, -1)
verts["L"].append(
[
(j + dx, s[k][j] + dy)
for dx, dy in [(0, 0), (-1, 0), (-1, -1), (0, -1)]
]
)
else:
# (0, 0)
# /|
# / |
# (-1, -1) | | (0, -1)
# | /
# |/
# (-1, -2)
verts["R"].append(
try: # try-else allows you to draw a subset of the paths without raising errors
if k > 0:
if s[k][j] == s[k][j - 1]:
# (-1, 0)
# |\
# | \ (0, 0)
# (-1, -1) | |
# \ |
# \|
# (0, -1)
verts["L"].append(
[
(j + dx, s[k][j] + dy)
for dx, dy in [(0, 0), (-1, 0), (-1, -1), (0, -1)]
]
)
else:
# (0, 0)
# /|
# / |
# (-1, -1) | | (0, -1)
# | /
# |/
# (-1, -2)
verts["R"].append(
[
(j + dx, s[k][j] + dy)
for dx, dy in [(0, 0), (-1, -1), (-1, -2), (0, -1)]
]
)

for l in range(s[k][j] + 1, s[k + 1][j]):
# (0, 0)
# /\
# (-1, -1) / \ (1, 0)
# \ /
# \/
# (0, -1)
verts["T"].append(
[
(j + dx, s[k][j] + dy)
for dx, dy in [(0, 0), (-1, -1), (-1, -2), (0, -1)]
(j + dx, l + dy)
for dx, dy in [(0, 0), (-1, -1), (0, -1), (1, 0)]
]
)

for l in range(s[k][j] + 1, s[k + 1][j]):
# (0, 0)
# /\
# (-1, -1) / \ (1, 0)
# \ /
# \/
# (0, -1)
verts["T"].append(
[
(j + dx, l + dy)
for dx, dy in [(0, 0), (-1, -1), (0, -1), (1, 0)]
]
)
except IndexError:
pass
return verts
40 changes: 25 additions & 15 deletions src/cftp/cftp/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@


def dir(angle_in_degree):
"""Return the unit complex cos(a) + i*sin(a).
"""
"""Return the unit complex cos(a) + i*sin(a)."""
theta = np.radians(angle_in_degree)
return complex(np.cos(theta), np.sin(theta))


def plot_line(ax, points, *args, **kwargs):
"""Connect a list of complex points with piecewise line segments.
"""
"""Connect a list of complex points with piecewise line segments."""
xli = [z.real for z in points]
yli = [z.imag for z in points]
return ax.plot(xli, yli, *args, **kwargs)
Expand All @@ -42,30 +40,42 @@ def draw_bounding_polygon(ax, vertices):
return patch


def draw_background_triangle_lattice(ax, dirs, N):
def draw_background_triangle_lattice(ax, dirs, hexagon_size):
"""Draw the background triangle grids for lozenge tilings.
:param ax: an instance of matplotlib's axes class.
:param dirs: three grid directions of the triangle grids.
:param N: how many lines we draw in each direction.
:param hexagon_size: A triple of integers (a, b, c) for the size of hexagon.
"""
lines = []
d = sq3 / 2
for v in dirs:
u = v * 1j
for i in range(-N, N + 1):
z1 = u * d * i - N * v
z2 = u * d * i + N * v
a, b, c = hexagon_size
X, Y, Z = dirs
N = max(a, b, c)
o = b * Z
for i in range(-N, N):
for start, end in [
(o - N * Z + i * X, o + N * Z + i * X),
(o - N * Y + i * d, o + N * Y + i * d),
(o - N * X + i * Z, o + N * X + i * Z),
]:
lines.extend(
plot_line(ax, [z1, z2], "--", color="gray", lw=1)
ax.plot(
[start.real, end.real],
[start.imag, end.imag],
"--",
color=(0.5, 0.5, 0.5),
lw=0.5,
)
)
return lines


def draw_marker(ax, z, label):
plot_line(ax, [z, z], 'go', markersize=markersize)
ax.text(z.real, z.imag, label, fontsize=labelsize,
color="w", ha="center", va="center")
plot_line(ax, [z, z], "go", markersize=markersize)
ax.text(
z.real, z.imag, label, fontsize=labelsize, color="w", ha="center", va="center"
)


def draw_paths_on_hexagon(ax, XYZ, paths):
Expand Down
11 changes: 6 additions & 5 deletions src/cftp/example_random_lozenge_tiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
Draw a random lozenge tiling and its non-intersecting lattice paths
"""
import matplotlib.pyplot as plt

plt.rcParams.update({"text.usetex": True, "font.family": "Courier"})

from cftp import LozengeTiling
import cftp.utils as utils

Expand Down Expand Up @@ -31,14 +34,12 @@ def main(hexagon_size, figsize):
ax.axis("off")

patch = utils.draw_bounding_polygon(ax, verts)
lines = utils.draw_background_triangle_lattice(
ax, (X, Y, Z), N
)
lines = utils.draw_background_triangle_lattice(ax, (X, Y, Z), hexagon_size)
for line in lines:
line.set_clip_path(patch)

# add text annotations
fs = 20
fs = 30
z = B + C + A / 2
ax.text(z.real + 0.5, z.imag + 0.8, "$a$", fontsize=fs)
z = B + C / 2
Expand All @@ -47,7 +48,7 @@ def main(hexagon_size, figsize):
ax.text(z.real - 1, z.imag, "$c$", fontsize=fs)

# draw the background hexagon
fig.savefig("hexagon.png")
fig.savefig("hexagon.svg")

# remove background grid lines
for line in lines:
Expand Down

0 comments on commit fc7cdf8

Please sign in to comment.