Skip to content

Instantly share code, notes, and snippets.

@neozhaoliang
Created August 19, 2025 13:45
Show Gist options
  • Select an option

  • Save neozhaoliang/107188869acc654ef5965bf9aa798c49 to your computer and use it in GitHub Desktop.

Select an option

Save neozhaoliang/107188869acc654ef5965bf9aa798c49 to your computer and use it in GitHub Desktop.
import collections
import mpmath as mp
import matplotlib.pyplot as plt
mp.dps = 100
alpha = beta = 2.2
sq2 = mp.sqrt(2)
gamma = (alpha * beta + mp.sqrt(alpha * alpha * beta * beta + 8 - 4 * (alpha * alpha+beta*beta)) )/ 2
delta = ((gamma - 2) * (beta + sq2)) / (beta * gamma - 2 * alpha + sq2 * 1j * gamma)
a11 = alpha / 2
a12 = (alpha * gamma - 2 * beta + 2j * sq2) / ((2 * gamma + 4) * delta)
a21 = (alpha * gamma - 2 * beta - 2j * sq2) * delta / (2 * gamma - 4)
a22 = alpha / 2
a = mp.matrix([[a11, a12], [a21, a22]])
b11 = (beta - sq2 * 1j) / 2
b12 = (beta * gamma - 2 * alpha - sq2 * 1j * gamma) / ((2 * gamma + 4) * delta)
b21 = (beta * gamma - 2 * alpha + sq2 * 1j * gamma) * delta / (2 * gamma - 4)
b22 = (beta + sq2 * 1j) / 2
b = mp.matrix([[b11, b12], [b21, b22]])
A = mp.matrix([[a22, -a12], [-a21, a11]])
B = mp.matrix([[b22, -b12], [-b21, b11]])
I = mp.matrix([[1, 0], [0, 1]])
table = {
"I": ["a", "b", "A", "B"],
"a": ["a", "ab", None, "B"],
"b": ["ba", "b", "bA", None],
"A": [None, "b", "A", "AB"],
"B": ["Ba", None, "BA", "B"],
"ab": ["ba", "b", "abA", None],
"AB": ["ABa", None, "BA", "B"],
"ba": ["a", "ab", None, "baB"],
"bA": [None, "b", "A", "bAB"],
"Ba": ["a", "Bab", None, "B"],
"BA": [None, "BAb", "A", "B"],
"abA": [None, "b", "A", "abAB"],
"ABa": ["a", "ABab", None, "B"],
"baB": ["Ba", None, None, "B"],
"bAB": [None, None, "BA", "B"],
"Bab": ["ba", "b", None, None],
"BAb": [None, "b", "bA", None],
"abAB": [None, None, "BA", "B"],
"ABab": ["ba", "b", None, None],
}
keys = list(table.keys())
def build_dict(li):
d = {}
for index, symbol in enumerate(["a", "b", "A", "B"]):
pattern = li[index]
if pattern is not None:
d[symbol] = keys.index(pattern)
return d
AUTOMATON = {i: build_dict(table[keys[i]]) for i in range(len(keys))}
print(AUTOMATON)
def generate_group_elements(max_len):
mats = []
queue = collections.deque([("", 0, I)])
while queue:
word, state, M = queue.popleft()
mats.append(M)
if len(word) < max_len:
for symbol, to in AUTOMATON[state].items():
queue.append(
(word + symbol, to, M @ {"a": a, "b": b, "A": A, "B": B}[symbol])
)
return mats
mats = generate_group_elements(8)
xmin, xmax = -0.5, 0.5
ymin, ymax = -0.5, 0.5
image_width = 1000
image_height = 1000
super_sampling_level = 1
num_octaves = 4
num_steps = 8
zoom_factor = 10
grid_opacity = 0.5
shading_opacity = 0.16
def iterate(z):
upper = mp.mpc(0)
lower = mp.mpc(0)
for m in mats:
upper += 1 / ((m[0, 0] * z + m[0, 1]) * (m[1, 0] * z + m[1, 1]) ** 3)
lower += 1 / (m[1, 0] * z + m[1, 1]) ** 4
return upper / lower
mp.cplot(
iterate, re=[-0.4, 0.4], im=[-0.4, 0.4], points=1000000, verbose=True, file="klein.png"
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment